首页 > 代码库 > hdu_5919_Sequence II(主席树)

hdu_5919_Sequence II(主席树)

题目链接:hdu_5919_Sequence II

题意:

给你n个数,m个询问,每次问你一个区间中每一种数在区间中第一次出现的位置的中位数,强制在线。

题解:

一看就是主席树搞,不过这里要询问第一次出现的位置,有个技巧就是倒着将数插进去,如果有相同的数,就把位置靠后的数的贡献取消掉,这样查询的时候就只需要查询root[l]了,因为root[l]包括了l到n的信息,前面已经只保留了相同数的最前面的位置,所以查询一共有多少种数时直接查询root[l]的l到r就行了。

技术分享
 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;i++)
 3 using namespace std;
 4 
 5 const int N=2e5+7;
 6 struct node{int l,r,sum;}T[40*N];
 7 
 8 int t,n,m,a[N],pre[N],root[N],tot,ic=1;
 9 
10 void update(int &x,int y,int pos,int val,int l=1,int r=n)
11 {
12     T[++tot]=x?T[x]:T[y],T[tot].sum+=val,x=tot;
13     if(l==r)return;
14     int m=l+r>>1;
15     if(pos<=m)update(T[x].l,T[y].l,pos,val,l,m);
16     else update(T[x].r,T[y].r,pos,val,m+1,r);
17 }
18 
19 int query(int x,int k,int l=1,int r=n)
20 {
21     if(l==r)return l;
22     int m=l+r>>1;
23     if(k<=T[T[x].l].sum)return query(T[x].l,k,l,m);
24     return query(T[x].r,k-T[T[x].l].sum,m+1,r);
25 }
26 
27 int getsum(int x,int L,int R,int l=1,int r=n)
28 {
29     if(L<=l&&r<=R)return T[x].sum;
30     int m=l+r>>1,ans=0;
31     if(L<=m)ans+=getsum(T[x].l,L,R,l,m);
32     if(R>m)ans+=getsum(T[x].r,L,R,m+1,r);
33     return ans;
34 }
35 
36 int main()
37 {
38     scanf("%d",&t);
39     while(t--)
40     {
41         printf("Case #%d: ",ic++);
42         scanf("%d%d",&n,&m);
43         tot=0;
44         F(i,1,n)scanf("%d",a+i);
45         for(int i=n;i>0;i--)
46         {
47             if(pre[a[i]])update(root[i],root[i+1],pre[a[i]],-1);
48             update(root[i],root[i+1],i,1);
49             pre[a[i]]=i;
50         }
51         int ans=0,l,r,sum;
52         F(i,1,m)
53         {
54             scanf("%d%d",&l,&r);
55             l=(l+ans)%n+1,r=(r+ans)%n+1;
56             if(l>r)l^=r,r^=l,l^=r;
57             sum=getsum(root[l],l,r);
58             printf("%d%c",ans=query(root[l],sum+1>>1)," \n"[i==m]);
59         }
60         while(tot)T[tot].l=T[tot].r=T[tot].sum=0,tot--;
61         F(i,1,n)root[i]=0,pre[a[i]]=0;
62     }
63     return 0;
64 }
View Code

 

hdu_5919_Sequence II(主席树)