[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)$,可以通过

  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 }
View Code

 

posted @ 2021-08-01 11:23  PYWBKTDA  阅读(67)  评论(0编辑  收藏  举报