bzoj3052 [wc2013]糖果公园 (树上带修改莫队)
2017-11-27 21:31
495 查看
bzoj3052 [wc2013]糖果公园
原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3052题意:
(权限题贴题面)
Input
4 3 5
1 9 2
7 6 5 1
2 3
3 1
3 4
1 2 3 2
1 1 2
1 4 2
0 2 1
1 1 2
1 4 2
Output
84
131
27
84
数据范围
题解:
关于树上莫队转序列莫队:
遍历一棵树记录in,out得到一个括号序:
例如:
得到:
1 2 3 3 2 4 10 8 8 5 5 10 4 6 7 7 9 9 6 1
对于两个点u,v的链: (in[u] < in[v])
1.u是v的祖先:从in[u]到in[v],中间出现两次的(in,out)的消掉,剩下的序列。
2.u不是v的祖先:从out[u]到in[v],中间出现两次的(in,out)的消掉,剩下的序列。
这个出现两次消掉就开个数序记录一下。
带修莫队见此
于是这道题就是裸题。
今天卡了一发评测,不仅第一次交没过(还是因为cmp写错TLE),还手滑连续交了两发TLE,还用的是别人的号233。
不远就听见Mercer在那骂:哪个sb交糖果公园还交两发。
以为没被认出来正在那庆幸,就被wys揭发了…
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #define LL long long using namespace std; const int N=200005; const int MXN=1000006; const int P=17; int n,m,q,col ,st ,cnt ,V ,W ,head ,to[2*N],nxt[2*N],num=0,blo; int qs=0,md=0; LL sum ,ans ,now=0,vis[2*N]; int dep ,anc [P+3],in ,out ,seq[2*N],inc=0; void build(int u,int v) { num++; to[num]=v; nxt[num]=head[u]; head[u]=num; } void dfs(int u,int f) { inc++; seq[inc]=u; in[u]=inc; dep[u]=dep[f]+1; anc[u][0]=f; for(int i=1;i<P;i++) anc[u][i]=anc[anc[u][i-1]][i-1]; for(int i=head[u];i;i=nxt[i]) { int v=to[i]; if(v==f) continue; dfs(v,u); } inc++; seq[inc]=u; out[u]=inc; } struct Query { int L,R,t,id,pos; }Q ; struct Modify { int pos,pre,nxt; }M ; int getlca(int u,int v) { if(dep[u]<dep[v]) swap(u,v); int d=dep[u]-dep[v]; for(int i=0;d;d>>=1,i++) if(d&1) u=anc[u][i]; if(u==v) return u; for(int i=P-1;i>=0;i--) if(anc[u][i]!=anc[v][i]) {u=anc[u][i]; v=anc[v][i]; } return anc[u][0]; } int getb(int x) {return (x-1)/blo+1;} bool cmp(const Query &A,const Query &B) { if(getb(A.L)!=getb(B.L)) return A.L<B.L; else if(getb(A.R)!=getb(B.R)) return A.R<B.R; else return A.t<B.t; } void modify(int pos,int opt) { int u=seq[pos]; now-=1LL*sum[cnt[col[u]]]*1LL*V[col[u]]; vis[u]^=1; if(vis[u]) cnt[col[u]]++; else cnt[col[u]]--; now+=1LL*sum[cnt[col[u]]]*1LL*V[col[u]]; } void change(int tim,int opt) { int pre=M[tim].pre; int nxt=M[tim].nxt; int pos=M[tim].pos; if(vis[pos]) { now-=1LL*sum[cnt[col[pos]]]*1LL*V[col[pos]]; cnt[col[pos]]--; now+=1LL*sum[cnt[col[pos]]]*1LL*V[col[pos]]; col[pos]= opt>0? nxt:pre; now-=1LL*sum[cnt[col[pos]]]*1LL*V[col[pos]]; cnt[col[pos]]++; now+=1LL*sum[cnt[col[pos]]]*1LL*V[col[pos]]; } else col[pos]= opt>0? nxt:pre; } void moto() { int lf=1,rg=0,cur=0; for(int i=1;i<=qs;i++) { while(rg<Q[i].R) modify(++rg,1); while(lf>Q[i].L) modify(--lf,1); while(rg>Q[i].R) modify(rg--,-1); while(lf<Q[i].L) modify(lf++,-1); while(cur<Q[i].t) change(++cur,1); while(cur>Q[i].t) change(cur--,-1); int lca=Q[i].pos; ans[Q[i].id]=now; if(lca) { ans[Q[i].id]-=1LL*sum[cnt[col[lca]]]*1LL*V[col[lca]]; ans[Q[i].id]+=1LL*sum[cnt[col[lca]]+1]*1LL*V[col[lca]]; } } } int main() { scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=m;i++) scanf("%d",&V[i]); for(int i=1;i<=n;i++) scanf("%d",&W[i]); sum[0]=0; for(int i=1;i<=n;i++) sum[i]=sum[i-1]+1LL*W[i]; for(int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); build(u,v); build(v,u); } for(int i=1;i<=n;i++) {scanf("%d",&col[i]); st[i]=col[i];} dfs(1,1); blo=(int)pow((double)inc,(double)2/3); for(int i=1;i<=q;i++) { int opt,x,y; scanf("%d%d%d",&opt,&x,&y); if(opt==0) { md++; M[md].pre=col[x]; M[md].pos=x;col[x]=y; M[md].nxt=y; } else { qs++; Q[qs].id=qs; Q[qs].t=md; int lca=getlca(x,y); if(dep[x]>dep[y]) swap(x,y); if(lca!=x) Q[qs].pos=lca; else Q[qs].pos=0; if(in[x]>in[y]) swap(x,y); Q[qs].R=in[y]; Q[qs].L=(out[x]>in[y])? in[x]:out[x]; } } for(int i=1;i<=n;i++) col[i]=st[i]; sort(Q+1,Q+qs+1,cmp); moto(); for(int i=1;i<=qs;i++) printf("%lld\n",ans[i]); return 0; }
相关文章推荐
- bzoj 3052: [wc2013]糖果公园【树上带修改莫队】
- 【BZOJ3052】[wc2013]糖果公园 带修改的树上莫队
- BZOJ 3052 WC2013 糖果公园 带修改树上莫队
- uoj#58./bzoj3052 【WC2013】糖果公园 //树上带修改莫队
- [BZOJ 3052][wc2013]糖果公园:树上带修改莫队
- 【bzoj3052】[wc2013]糖果公园 带修改树上莫队
- bzoj3052 [wc2013]糖果公园(树上莫队,带修改)
- bzoj 3052: [wc2013]糖果公园(带修改的树上莫队)
- [BZOJ3052][wc2013]糖果公园(树上带修改莫队)
- BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)
- [BZOJ3052][WC2013]糖果公园(树上莫队修改)
- [BZOJ3052]-[WC2013]糖果公园-树上带修改莫队-200题纪念!!!
- 【树上莫队】【带修莫队】bzoj3052 [wc2013]糖果公园
- BZOJ 3052: [wc2013]糖果公园 树上莫队
- bzoj 3052: [wc2013]糖果公园 带修改莫队
- 【BZOJ3052】【UOJ#58】【WC2013】糖果公园(树上莫队)
- [树上带修莫队] BZOJ3052: [WC2013]糖果公园
- [BZOJ3052][WC2013]糖果公园-树上带修改莫队算法
- BZOJ3052 [wc2013] 糖果公园 【树上莫队】
- BZOJ 3052 [wc2013]糖果公园 树上莫队