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 }