bzoj 1162 network
树上的区间第k小数,以前写的主席树是一直MLE的,后来看到一种在初始化的时候的优化:直接DFS这颗树,得到每个点的主席树,然后更新的时候另外对DFS序建主席树,答案加上初始每个点的主席树,这样在初始化每个点的时候就不需要用BIT维护了,省去的空间正好AC了这个题。
呆马:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstring> 6 #include <vector> 7 #define maxn 80008 8 using namespace std; 9 struct node 10 { 11 node *lc,*rc; 12 int s; 13 node () {s=0;} 14 }*rot[maxn],*sum[maxn],*p; 15 vector <node*> st[4]; 16 struct et 17 { 18 int s,t,next; 19 }e[maxn*2]; 20 int ll[maxn],rr[maxn],fir[maxn],key[maxn]; 21 int w[maxn*2],dep[maxn],fa[maxn][20]; 22 int x[maxn],y[maxn],z[maxn]; 23 int n,m,tot,low,cnt,num; 24 int v[5]; 25 26 node *build(int l,int r) 27 { 28 node *now=new node(); 29 if (l==r) return now; 30 int mid=(l+r)>>1; 31 now->lc=build(l,mid); 32 now->rc=build(mid+1,r); 33 return now; 34 } 35 36 node *change(int l,int r,int x,int z) 37 { 38 node *now=new node(); 39 now->lc=p->lc; now->rc=p->rc; 40 now->s=p->s+z; 41 if (l==r) return now; 42 int mid=(l+r)>>1; 43 if (x<=mid) p=p->lc,now->lc=change(l,mid,x,z); 44 else p=p->rc,now->rc=change(mid+1,r,x,z); 45 return now; 46 } 47 48 void adj(int x,int y,int z) 49 { 50 if (x==0) return ; 51 for (int i=x;i<=n;i+=(i&-i)) p=rot[i],rot[i]=change(0,num,y,z); 52 } 53 54 void fill(int k) 55 { 56 st[k].clear(); 57 st[k].push_back(sum[v[k]]); 58 for (int i=ll[v[k]];i>0;i-=(i&-i)) st[k].push_back(rot[i]); 59 } 60 61 int getsum(int k) 62 { 63 int ans=0, n=st[k].size(); 64 for (int i=0;i<n;i++) ans+=st[k][i]->s; 65 return ans; 66 } 67 68 int getsize(int k) 69 { 70 int ans=0, n=st[k].size(); 71 for (int i=0;i<n;i++) ans+=st[k][i]->rc->s; 72 return ans; 73 } 74 75 void goleft(int k) 76 { 77 int n=st[k].size(); 78 for (int i=0;i<n;i++) st[k][i]=st[k][i]->lc; 79 } 80 81 void goright(int k) 82 { 83 int n=st[k].size(); 84 for (int i=0;i<n;i++) st[k][i]=st[k][i]->rc; 85 } 86 87 int query(int l,int r,int k) 88 { 89 if (k>getsum(1)+getsum(2)-getsum(3)-getsum(4)) return 0; 90 if (l==r) return l; 91 int tmp=getsize(1)+getsize(2)-getsize(3)-getsize(4); 92 int mid=(l+r)>>1; 93 if (k<=tmp) 94 { 95 goright(1),goright(2),goright(3),goright(4); 96 return query(mid+1,r,k); 97 } 98 else 99 { 100 goleft(1),goleft(2),goleft(3),goleft(4); 101 return query(l,mid,k-tmp); 102 } 103 } 104 105 int lca(int x,int y) 106 { 107 if (dep[x]>dep[y]) swap(x,y); 108 for (int i=low;i>=0;i--) 109 if (dep[fa[y][i]]>=dep[x]) y=fa[y][i]; 110 if (x==y) return x; 111 for (int i=low;i>=0;i--) 112 if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; 113 return fa[x][0]; 114 } 115 116 void write(node *now,int l,int r) 117 { 118 if (l==r) 119 { 120 cout<<now->s; 121 return ; 122 } 123 int mid=(l+r)>>1; 124 write(now->lc,l,mid); 125 write(now->rc,mid+1,r); 126 } 127 128 void dfs(int now) 129 { 130 ll[now]=rr[now]=++cnt; 131 p=sum[fa[now][0]]; 132 sum[now]=change(0,num,key[now],1); 133 134 for (int j=fir[now];j;j=e[j].next) 135 { 136 int k=e[j].t; 137 if (fa[now][0]!=k) 138 { 139 fa[k][0]=now; dep[k]=dep[now]+1; 140 for (int i=1;i<=low;i++) fa[k][i]=fa[fa[k][i-1]][i-1]; 141 dfs(k); 142 rr[now]=rr[k]; 143 } 144 } 145 } 146 147 void add(int x,int y) 148 { 149 e[++tot].s=x; e[tot].t=y; e[tot].next=fir[x]; fir[x]=tot; 150 e[++tot].s=y; e[tot].t=x; e[tot].next=fir[y]; fir[y]=tot; 151 } 152 153 int main() 154 { 155 //freopen("network10.in","r",stdin); 156 //freopen("network.out","w",stdout); 157 scanf("%d%d",&n,&m); 158 low=log(n)/log(2.0); 159 for (int i=1;i<=n;i++) scanf("%d",&key[i]),w[++num]=key[i]; 160 int st,ed; 161 for (int i=1;i<n;i++) scanf("%d%d",&st,&ed),add(st,ed); 162 num=n; 163 for (int i=1;i<=m;i++) 164 { 165 scanf("%d%d%d",&z[i],&x[i],&y[i]); 166 if (!z[i]) w[++num]=y[i]; 167 } 168 sort(w+1,w+num+1); 169 num=unique(w+1,w+num+1)-w; 170 for (int i=1;i<=n;i++) key[i]=lower_bound(w+1, w+num+1, key[i])-w; 171 for (int i=1;i<=m;i++) if (!z[i]) y[i]=lower_bound(w+1, w+num+1, y[i])-w; 172 173 sum[0]=rot[0]=build(0,num); 174 for (int i=1;i<=n;i++) rot[i]=rot[0]; 175 int root=rand()%n+1; dep[root]=1; 176 dfs(root); 177 178 for (int i=1;i<=m;i++) 179 { 180 if (z[i]) 181 { 182 int tmp; 183 v[1]=x[i],v[2]=y[i],v[3]=tmp=lca(x[i],y[i]),v[4]=fa[tmp][0]; 184 fill(1); fill(2); fill(3); fill(4); 185 int ans=query(0,num,z[i]); 186 if (ans) 187 printf("%d\n",w[ans]); 188 else 189 printf("invalid request!\n"); 190 } 191 else 192 { 193 adj(ll[x[i]],key[x[i]],-1),adj(rr[x[i]]+1,key[x[i]],1); 194 key[x[i]]=y[i]; 195 adj(ll[x[i]],key[x[i]],1),adj(rr[x[i]]+1,key[x[i]],-1); 196 } 197 } 198 return 0; 199 }
AC without art, no better than WA !