[hdu6973]Bookshop
将询问拆成$x$到$lca$和$lca$($lca$靠近$y$的儿子)到$y$两部分,分别处理(后者以前者的答案为基础)
两者是类似地,不妨仅考虑前者:用树剖将该询问拆成dfs序上若干个区间,考虑从后往前遍历dfs序(显然即从下到上),若当前位置被覆盖则执行该节点的操作
进一步的,考虑将一个位置上的操作对覆盖其的位置批量处理,即将问题离线并维护一棵平衡树,仍从后往前遍历dfs序,并支持:
1.(在区间右端点时)加入一个数
2.将当前平衡树中大于等于$k$的数都减去$k$
3.(在区间左端点时)删除一个数
前两个容易处理(删除可以将下标定为询问编号),对于第三个,对权值分类讨论:
1.权值在$[0,k)$中的数不需要处理
2.权值在$[k,2k)$中的数,每一个数至多经历$o(\log V)$次此操作即会变为0(之后显然就不会被操作了),将这些数取出后再暴力操作,复杂度为$o(q\log n\log V)$
3.权值在$[2k,\infty)$中的数,打懒标记即可(第2类需要暴力处理因为要考虑与$[0,k)$中的数的排名)
总复杂度即$o(n\log ^{2}n)$,可以通过
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 #define pii pair<int,int> 5 #define mp make_pair 6 #define fi first 7 #define se second 8 #define s(p) f[k].ch[p] 9 vector<int>v,va[N],vd[N]; 10 vector<pii>v0[N],v1[N]; 11 int E,rt,t,n,q,x,y,head[N],a[N],st[N],fa[N],sz[N],mx[N],dep[N],dfn[N],idfn[N],top[N]; 12 struct Edge{ 13 int nex,to; 14 }edge[N<<1]; 15 struct Data{ 16 int fa,val,mx,mn,tag,ch[2]; 17 }f[N]; 18 void add_edge(int x,int y){ 19 edge[E].nex=head[x]; 20 edge[E].to=y; 21 head[x]=E++; 22 } 23 void dfs1(int k,int f,int s){ 24 fa[k]=f,sz[k]=1,mx[k]=0,dep[k]=s; 25 for(int i=head[k];i!=-1;i=edge[i].nex) 26 if (edge[i].to!=f){ 27 dfs1(edge[i].to,k,s+1); 28 sz[k]+=sz[edge[i].to]; 29 if (sz[mx[k]]<sz[edge[i].to])mx[k]=edge[i].to; 30 } 31 } 32 void dfs2(int k,int fa,int t){ 33 dfn[k]=++dfn[0],idfn[dfn[0]]=k,top[k]=t; 34 if (mx[k])dfs2(mx[k],k,t); 35 for(int i=head[k];i!=-1;i=edge[i].nex) 36 if ((edge[i].to!=fa)&&(edge[i].to!=mx[k]))dfs2(edge[i].to,k,edge[i].to); 37 } 38 int check(int k){ 39 return f[f[k].fa].ch[1]==k; 40 } 41 bool cmp(int x,int y){ 42 return (f[x].val<f[y].val)||(f[x].val==f[y].val)&&(x<y); 43 } 44 void upd(int k,int x){ 45 f[k].val+=x,f[k].mx+=x,f[k].mn+=x,f[k].tag+=x; 46 } 47 void up(int k){ 48 f[k].mx=max(max(f[s(0)].mx,f[s(1)].mx),f[k].val); 49 f[k].mn=min(min(f[s(0)].mn,f[s(1)].mn),f[k].val); 50 } 51 void down(int k){ 52 if (s(0))upd(s(0),f[k].tag); 53 if (s(1))upd(s(1),f[k].tag); 54 f[k].tag=0; 55 } 56 void rotate(int k){ 57 int F=f[k].fa,G=f[F].fa,p=check(k); 58 f[k].fa=G; 59 if (G)f[G].ch[check(F)]=k; 60 f[s(p^1)].fa=F,f[F].ch[p]=s(p^1); 61 f[F].fa=k,s(p^1)=F; 62 up(F),up(k); 63 } 64 void clear(int k){ 65 for(int i=k;i;i=f[i].fa)st[++st[0]]=i; 66 while (st[0])down(st[st[0]--]); 67 } 68 void splay(int k,int fa){ 69 clear(k); 70 for(int i=f[k].fa;i!=fa;i=f[k].fa){ 71 if (f[i].fa!=fa){ 72 if (check(i)==check(k))rotate(i); 73 else rotate(k); 74 } 75 rotate(k); 76 } 77 if (!fa)rt=k; 78 } 79 void get_val(int k){ 80 if (!k)return; 81 v.push_back(k); 82 get_val(s(0)); 83 get_val(s(1)); 84 } 85 int find_pre(int k,int x){ 86 if (!k)return 0; 87 down(k); 88 if (!cmp(k,x))return find_pre(s(0),x); 89 int ans=find_pre(s(1),x); 90 if (ans)return ans; 91 return k; 92 } 93 int find_nex(int k,int x){ 94 if (!k)return 0; 95 down(k); 96 if (!cmp(x,k))return find_nex(s(1),x); 97 int ans=find_nex(s(0),x); 98 if (ans)return ans; 99 return k; 100 } 101 void add(int k){ 102 clear(k); 103 int l=find_pre(rt,k),r=find_nex(rt,k); 104 if (!l){ 105 if (!r)rt=k; 106 else{ 107 splay(r,0); 108 f[k].fa=rt,f[rt].ch[0]=k; 109 up(rt); 110 } 111 } 112 else{ 113 splay(l,0); 114 if (!r){ 115 f[k].fa=rt,f[rt].ch[1]=k; 116 up(rt); 117 } 118 else{ 119 splay(r,rt); 120 f[k].fa=f[rt].ch[1],f[f[rt].ch[1]].ch[0]=k; 121 up(f[rt].ch[1]),up(rt); 122 } 123 } 124 } 125 void dec(int k){ 126 clear(k); 127 int l=find_pre(rt,k),r=find_nex(rt,k); 128 if (!l){ 129 if (!r)rt=0; 130 else{ 131 splay(r,0); 132 f[rt].ch[0]=0; 133 up(rt); 134 } 135 } 136 else{ 137 splay(l,0); 138 if (!r){ 139 f[rt].ch[1]=0; 140 up(rt); 141 } 142 else{ 143 splay(r,rt); 144 f[f[rt].ch[1]].ch[0]=0; 145 up(f[rt].ch[1]),up(rt); 146 } 147 } 148 f[k].fa=0; 149 } 150 void update_force(int x,int y,int z){ 151 v.clear(); 152 f[0].val=x,f[q+1].val=y; 153 int l=find_pre(rt,0),r=find_nex(rt,q+1); 154 if (!l){ 155 if (!r)get_val(rt); 156 else{ 157 splay(r,0); 158 get_val(f[rt].ch[0]); 159 up(rt); 160 } 161 } 162 else{ 163 splay(l,0); 164 if (!r){ 165 get_val(f[rt].ch[1]); 166 up(rt); 167 } 168 else{ 169 splay(r,rt); 170 get_val(f[f[rt].ch[1]].ch[0]); 171 up(f[rt].ch[1]),up(rt); 172 } 173 } 174 for(int i=0;i<v.size();i++){ 175 dec(v[i]); 176 f[v[i]].val+=z; 177 add(v[i]); 178 } 179 } 180 void update_tag(int x,int y,int z){ 181 f[0].val=x,f[q+1].val=y; 182 int l=find_pre(rt,0),r=find_nex(rt,q+1); 183 if (!l){ 184 if (!r)upd(rt,z); 185 else{ 186 splay(r,0); 187 upd(f[rt].ch[0],z); 188 up(rt); 189 } 190 } 191 else{ 192 splay(l,0); 193 if (!r){ 194 upd(f[rt].ch[1],z); 195 up(rt); 196 } 197 else{ 198 splay(r,rt); 199 upd(f[f[rt].ch[1]].ch[0],z); 200 up(f[rt].ch[1]),up(rt); 201 } 202 } 203 } 204 int main(){ 205 f[0].mn=0x3f3f3f3f; 206 scanf("%d",&t); 207 while (t--){ 208 scanf("%d%d",&n,&q); 209 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 210 E=dfn[0]=0; 211 for(int i=1;i<=n;i++)head[i]=-1; 212 for(int i=1;i<n;i++){ 213 scanf("%d%d",&x,&y); 214 add_edge(x,y); 215 add_edge(y,x); 216 } 217 dfs1(1,0,0); 218 dfs2(1,0,1); 219 for(int i=1;i<=q;i++){ 220 scanf("%d%d%d",&x,&y,&f[i].val); 221 v0[i].clear(),v1[i].clear(); 222 while (top[x]!=top[y]){ 223 if (dep[top[x]]>dep[top[y]]){ 224 v0[i].push_back(mp(dfn[x],dfn[top[x]])); 225 x=fa[top[x]]; 226 } 227 else{ 228 v1[i].push_back(mp(dfn[top[y]],dfn[y])); 229 y=fa[top[y]]; 230 } 231 } 232 if (dfn[x]>dfn[y])v0[i].push_back(mp(dfn[x],dfn[y])); 233 else v1[i].push_back(mp(dfn[x],dfn[y])); 234 } 235 for(int i=1;i<=n;i++)va[i].clear(),vd[i].clear(); 236 for(int i=1;i<=q;i++) 237 for(int j=0;j<v0[i].size();j++){ 238 va[v0[i][j].fi].push_back(i); 239 vd[v0[i][j].se].push_back(i); 240 } 241 rt=0; 242 for(int i=1;i<=q;i++){ 243 f[i].fa=f[i].tag=f[i].ch[0]=f[i].ch[1]=0; 244 f[i].mx=f[i].mn=f[i].val; 245 } 246 for(int i=n;i;i--){ 247 int k=a[idfn[i]]; 248 for(int j=0;j<va[i].size();j++)add(va[i][j]); 249 update_force(k,(k<<1)-1,-k); 250 update_tag((k<<1),1e9,-k); 251 for(int j=0;j<vd[i].size();j++)dec(vd[i][j]); 252 } 253 for(int i=1;i<=n;i++)va[i].clear(),vd[i].clear(); 254 for(int i=1;i<=q;i++) 255 for(int j=0;j<v1[i].size();j++){ 256 va[v1[i][j].fi].push_back(i); 257 vd[v1[i][j].se].push_back(i); 258 } 259 rt=0; 260 for(int i=1;i<=q;i++){ 261 f[i].fa=f[i].tag=f[i].ch[0]=f[i].ch[1]=0; 262 f[i].mx=f[i].mn=f[i].val; 263 } 264 for(int i=1;i<=n;i++){ 265 int k=a[idfn[i]]; 266 for(int j=0;j<va[i].size();j++)add(va[i][j]); 267 update_force(k,(k<<1)-1,-k); 268 update_tag((k<<1),1e9,-k); 269 for(int j=0;j<vd[i].size();j++)dec(vd[i][j]); 270 } 271 for(int i=1;i<=q;i++)printf("%d\n",f[i].val); 272 } 273 return 0; 274 }