HDU 5919 Sequence II [主席树]【数据结构】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5919 Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Problem Description In the
We can denote the positions(the positions according to the original sequence) where an integer appears first in this subsequence as
Note that ki is the number of different integers in this subsequence. You should output p(i)?ki2?for the i-th query. Input Each test case starts with two integers n
There are two integers
However,Mr. Frog thought that this problem was too young too simple so he became angry. He modified each query to
We can denote the answers as
You can get the correct input li,ri from what you read (we denote them as
Output For each test case,output one line “Case #x:
Sample Input Sample Output Hint ———————————————————————————————————————————— 题目大意: 解题思路: 然后他说在询问区间,不相同元素第一次出现的位置的中间那个, 这样的话就是主席树的基本操作了, 总体复杂度
附本题代码 #include <bits/stdc++.h>
using namespace std;
/**********************************/
const int N = 2e5+7;
int n,m,ans;
int a[N],vis[N];
void so(int &l,int &r){
int tem=(l+ans)%n+1;
int tmp=(r+ans)%n+1;
l=(tem<tmp)?tem:tmp;
r=(tem>tmp)?tem:tmp;
}
int rt[N],ls[N*40],rs[N*40],sum[N*40],tot;
void build(int& rt,int l,int r){
rt=++tot;
sum[rt]=0;
if(l>=r)return;
int m=((r-l)>>1)+l;
build(ls[rt],l,m);
build(rs[rt],m+1,r);
}
void update(int& rt,int r,int last,int pos,int v){
rt=++tot;
ls[rt]=ls[last];
rs[rt]=rs[last];
sum[rt]=sum[last]+v;
if(l>=r)return;
int m=((r-l)>>1)+l;
if(pos<=m) update(ls[rt],ls[last],pos,v);
else update(rs[rt],r,rs[last],v);
}
int query_num(int rt,int L,int R){
if(L<=l&&r<=R) return sum[rt];
int m=((r-l)>>1)+l;
int ans=0;
if(L<=m) ans+=query_num(ls[rt],L,R);
if(R> m) ans+=query_num(rs[rt],R);
return ans;
}
int query_id(int rt,int k){
if(l>=r)return l;
int m=((r-l)>>1)+l;
int cnt = sum[ls[rt]];
if(k<=cnt) return query_id(ls[rt],k);
else return query_id(rs[rt],k-cnt);
}
int main(){
int _=1,kcase=0;
scanf("%d",&_);
while(_--){
memset(vis,0,sizeof(vis));
ans = 0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
tot = 0;
build(rt[n+1],1,n);
for(int i=n,tem;i;i--){
tem=rt[i+1];
if(vis[a[i]])update(tem,n,rt[i+1],vis[a[i]],-1);
update(rt[i],tem,i,1);
vis[a[i]]=i;
}
printf("Case #%d:",++kcase);
for(int i=1,id;i<=m;i++){
scanf("%d%d",&l,&r);
so(l,r);
// printf("[%d,%d]",r);
id = query_num(rt[l],r);
// printf(" %d<=",id);
id =(id+1)>>1;
ans=query_id(rt[l],id);
printf(" %d",ans);
}
puts("");
}
return 0;
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |