bzoj 1146 [CTSC2008]网络管理Network

    很久之前写过 count on the tree。

    然后一直不懂树状数组是怎么套上这个主席树的。

    看了两小时发现它套的就是个权值线段树,

    看不出来可持久化在哪里。    

    因为动态开点所以空间nlog2n。

    树状数组维护dfs序,每个节点挂个线段树。

    为了省空间拿原树建了个主席树。

    

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #define N 80005
  6 using namespace std;
  7 int n,q;
  8 int t[N];
  9 int head[N],ver[N*2],nxt[N*2],tot;
 10 int li[N*2],now[N*2],cnt;
 11 void add(int a,int b)
 12 {
 13     tot++;nxt[tot]=head[a];head[a]=tot;ver[tot]=b;return ;
 14 }
 15 struct node 
 16 {
 17     int k,a,b;
 18 }qq[N];
 19 int zz,st[N],ed[N];
 20 int dep[N];
 21 int fa[N][18];
 22 void lca()
 23 {
 24     for(int i=1;i<=17;i++)
 25     for(int j=1;j<=n;j++)
 26     fa[j][i]=fa[fa[j][i-1]][i-1];
 27 }
 28 int lca(int x,int y)
 29 {
 30     if(dep[x]<dep[y])swap(x,y);
 31     for(int i=17;i>=0;i--)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
 32     if(x==y)return x;
 33     for(int i=17;i>=0;i--)
 34     {
 35         if(fa[x][i]!=fa[y][i])
 36         {
 37             x=fa[x][i];y=fa[y][i];
 38         }
 39     }
 40     return fa[x][0];
 41 }
 42 void dfs(int x,int f)
 43 {
 44     st[x]=++zz;
 45     for(int i=head[x];i;i=nxt[i])
 46     {
 47         if(ver[i]==f)continue;
 48         fa[ver[i]][0]=x;
 49         dep[ver[i]]=dep[x]+1;
 50         dfs(ver[i],x);
 51     }
 52     ed[x]=zz;
 53 }
 54 int root[N],rot[N];
 55 struct Node
 56 {
 57     int l,r,sum;
 58 }a[N*140];
 59 int num;
 60 
 61 void inrt(int x,int y,int l,int r,int pos)
 62 {
 63     if(l==r)
 64     {
 65         a[x].sum=a[y].sum+1;
 66         return ;
 67     }
 68     int mid=(l+r)>>1;
 69     if(pos<=mid)
 70     {
 71         if(!a[x].l)a[x].l=++num;
 72         a[x].r=a[y].r;
 73         inrt(a[x].l,a[y].l,l,mid,pos);
 74     }
 75     else
 76     {
 77         if(!a[x].r)a[x].r=++num;
 78         a[x].l=a[y].l;
 79         inrt(a[x].r,a[y].r,mid+1,r,pos);
 80     }
 81     a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
 82 }
 83 void build()
 84 {
 85     for(int i=1;i<=n;i++)
 86     {
 87         if(!rot[i])rot[i]=++num;
 88         inrt(rot[i],rot[fa[i][0]],1,cnt,now[i]);
 89     }
 90 }
 91 void insert(int x,int l,int r,int pos,int z)
 92 {
 93     if(l==r)
 94     {
 95         a[x].sum+=z;return ;
 96     }
 97     int mid=(l+r)>>1;
 98     if(pos<=mid)
 99     {
100         if(!a[x].l)a[x].l=++num;
101         insert(a[x].l,l,mid,pos,z);
102     }
103     else
104     {
105         if(!a[x].r)a[x].r=++num;
106         insert(a[x].r,mid+1,r,pos,z);
107     }
108     a[x].sum=a[a[x].l].sum+a[a[x].r].sum;
109 }
110 void ad(int x,int z,int la)
111 {
112     for(int i=x;i<=n;i+=(i&(-i)))
113     {
114         if(!root[i])root[i]=++num;
115         insert(root[i],1,cnt,z,la);
116     }
117     return ;
118 }
119 int no[N][4];
120 int t1,t2,t3,t4;
121 int qur(int x,int y)
122 {
123     int as=0;
124     for(int i=x;i;i-=(i&(-i)))
125     {
126         as+=a[a[no[i][y]].l].sum;
127     }
128     return as;
129 }
130 int qur(int l,int r,int kk,int r1,int r2,int r3,int r4)
131 {
132     if(l==r)
133     {
134         return l;
135     }
136     int mid=(l+r)>>1;
137     int xx=a[a[r3].l].sum+a[a[r4].l].sum-a[a[r1].l].sum-a[a[r2].l].sum;
138     xx+=qur(st[t1],0);xx+=qur(st[t2],1);
139     xx-=qur(st[t3],2);xx-=qur(st[t4],3);
140     if(xx>=kk)
141     {
142         for(int i=st[t1];i;i-=(i&(-i)))no[i][0]=a[no[i][0]].l;
143         for(int i=st[t2];i;i-=(i&(-i)))no[i][1]=a[no[i][1]].l;
144         for(int i=st[t3];i;i-=(i&(-i)))no[i][2]=a[no[i][2]].l;
145         for(int i=st[t4];i;i-=(i&(-i)))no[i][3]=a[no[i][3]].l;
146         return qur(l,mid,kk,a[r1].l,a[r2].l,a[r3].l,a[r4].l);
147     }
148     else
149     {
150         for(int i=st[t1];i;i-=(i&(-i)))no[i][0]=a[no[i][0]].r;
151         for(int i=st[t2];i;i-=(i&(-i)))no[i][1]=a[no[i][1]].r;
152         for(int i=st[t3];i;i-=(i&(-i)))no[i][2]=a[no[i][2]].r;
153         for(int i=st[t4];i;i-=(i&(-i)))no[i][3]=a[no[i][3]].r;
154         return qur(mid+1,r,kk-xx,a[r1].r,a[r2].r,a[r3].r,a[r4].r);
155     }
156 }
157 int main()
158 {
159     scanf("%d%d",&n,&q);
160     for(int i=1;i<=n;i++)scanf("%d",&t[i]),li[++cnt]=t[i];
161     for(int i=1;i<n;i++)
162     {
163         scanf("%d%d",&t1,&t2);
164         add(t1,t2);add(t2,t1);
165     }
166     for(int i=1;i<=q;i++)
167     {
168         scanf("%d%d%d",&qq[i].k,&qq[i].a,&qq[i].b);
169         if(!qq[i].k)li[++cnt]=qq[i].b;
170     }
171     sort(li+1,li+cnt+1);
172     cnt=unique(li+1,li+cnt+1)-li-1;
173     for(int i=1;i<=n;i++)now[i]=lower_bound(li+1,li+cnt+1,t[i])-li;
174     dep[1]=1;dfs(1,-1);
175     lca();
176     build();
177     for(int i=1;i<=q;i++)
178     {
179         if(!qq[i].k)
180         {
181             ad(st[qq[i].a],now[qq[i].a],-1);
182             if(ed[qq[i].a]!=zz)ad(ed[qq[i].a]+1,now[qq[i].a],1);
183             now[qq[i].a]=lower_bound(li+1,li+cnt+1,qq[i].b)-li;
184             ad(st[qq[i].a],now[qq[i].a],1);
185             if(ed[qq[i].a]!=zz)ad(ed[qq[i].a]+1,now[qq[i].a],-1);
186         }
187         else
188         {
189             int tmp=lca(qq[i].a,qq[i].b);
190             int yy=dep[qq[i].a]+dep[qq[i].b]-dep[tmp]*2+1;
191             if(yy<qq[i].k)
192             {
193                 puts("invalid request!");
194                 continue;
195             }
196             else
197             {
198                 yy=yy-qq[i].k+1;
199                 for(int j=st[qq[i].a];j;j-=(j&(-j)))no[j][0]=root[j];
200                 for(int j=st[qq[i].b];j;j-=(j&(-j)))no[j][1]=root[j];
201                 for(int j=st[tmp];j;j-=(j&(-j)))no[j][2]=root[j];
202                 for(int j=st[fa[tmp][0]];j;j-=(j&(-j)))no[j][3]=root[j];
203                 t1=qq[i].a;t2=qq[i].b;t3=tmp;t4=fa[tmp][0];
204                 int tp=qur(1,cnt,yy,rot[tmp],rot[fa[tmp][0]],rot[qq[i].a],rot[qq[i].b]);
205                 printf("%d\n",li[tp]);
206             }
207         }
208     }
209     return 0;
210 }

 

posted @ 2017-01-07 16:22  SD_le  阅读(162)  评论(0编辑  收藏  举报
重置按钮