您的位置:首页 > 产品设计 > UI/UE

hdu 5919Sequence II 主席数的应用 2016CCPC长春

2016-11-05 21:10 330 查看
传送门:Sequence II

题目大意

这个题目读题是个大困难呀,不好读;

给定一个长度为n的串,q次查询每次查询[L,R]区间中的数字的第一个在整个区间中的位置!强制在线操作;

解题思路

主席树的套路题目;知道主席树的人一定做过主席树的两种应用的题目就是求给定区间的第K大,还有给定区间[L,R],问这个区间中不同数字的个数!

这个题目就是对主席树的这两个应用的综合考察,我们先把这个序列从后向前的按照位置插入主席树,这样就能避免后面出现重复数字对前面的影响,然后我们求出这个区间中有k个不同的数字,我们只需要求出这个区间中第(k+1)/2大就可以了,在这里只要传查询第L棵树就可以了

AC代码

#include <cstdio>
#include <iostream>
#include <map>
#include <cstring>
using namespace std;
const int MX = 2e5+5;
const int N = MX*40;
int n,q,tot;
int A[MX];
int T
,lson
,rson
,sum
;

int build(int l,int r)
{
int rt = tot++;
sum[rt] = 0;
int mid = (l+r)>>1;
if(l!=r) {
lson[rt] = build(l,mid);
rson[rt] = build(mid+1,r);
}
return rt;
}
int update(int rt,int pos,int val)
{
int nrt = tot++;
int tmp = nrt;
int l=1,r=n;
sum[nrt] = sum[rt] + val;
while(l<r) {
int mid = (l+r)>>1;
if(pos<=mid) {
lson[nrt] = tot++;
rson[nrt] = rson[rt];
nrt = lson[nrt];
rt =  lson[rt];
r  = mid;
} else {
rson[nrt] = tot++;
lson[nrt] = lson[rt];
nrt = rson[nrt];
rt = rson[rt];
l = mid+1;
}
sum[nrt] = sum[rt]+val;
}
return tmp;
}
int query(int rt,int pos)
{
int cnt = 0;
int l = 1,r = n;
while(pos < r)
{
int mid = (l + r) >> 1;
if(pos <= mid)
{
rt = lson[rt];
r = mid;
}
else
{
cnt += sum[lson[rt]];
rt = rson[rt];
l = mid + 1;
}
}
return cnt + sum[rt];
}
int Query(int rt,int k)
{
int l = 1,r = n;
while(l < r){
int mid = (l + r) >> 1;
if(sum[lson[rt]] >= k){
rt = lson[rt];
r = mid;
}
else{
k -= sum[lson[rt]];
rt = rson[rt];
l = mid +1 ;
}
}
return l;
}
int main()
{
int _;
// freopen("in.txt","r",stdin);
scanf("%d",&_);
for(int cas=1;cas<=_;cas++) {
tot=0;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++) scanf("%d",&A[i]);
T[n+1] = build(1,n);
map<int,int>mp;
for(int i=n;i>0;i--) {
if(mp.find(A[i])==mp.end()) T[i] =  update(T[i+1],i,1);
else {
int tmp  = update(T[i+1],mp[A[i]],-1);
T[i]  = update(tmp,i,1);
}
mp[A[i]] = i;
}
int ans = 0;
printf("Case #%d:",cas);
while(q--)  {
int l,r;
scanf("%d%d",&l,&r);
l = (l+ans)%n+1;
r = (r+ans)%n+1;
int ll = min(l,r),rr = max(l,r);
int k = (query(T[ll],rr)+1)>>1;
if(!k) k=1;
ans = Query(T[ll],k);
printf(" %d",ans);
}
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: