【BZOJ 3052】 [wc2013]糖果公园
2015-01-28 20:39
253 查看
3052: [wc2013]糖果公园
Time Limit: 250 Sec Memory Limit: 512 MBSubmit: 481 Solved: 176
[Submit][Status]
Description
![](http://www.lydsy.com/JudgeOnline/upload/201302/1(1).jpg)
Input
![](http://www.lydsy.com/JudgeOnline/upload/201302/2(1).jpg)
Output
![](http://www.lydsy.com/JudgeOnline/upload/201302/3(1).jpg)
Sample Input
![](http://www.lydsy.com/JudgeOnline/upload/201302/4(1).jpg)
Sample Input
Sample Output
84131
27
84
HINT
![](http://www.lydsy.com/JudgeOnline/upload/201302/5(1).jpg)
![](http://www.lydsy.com/JudgeOnline/upload/201302/6(1).jpg)
带修改的树上莫队。
完成
【BZOJ 3757】(不带修改的树上莫队)之后,这道题就好理解了。
与bzoj3757一样,先对树分块,把询问以块和查询时间为关键字排序,关键就是转移了。
(curV,curU)到(targetV,targetU)的转移与bzoj3757一致,那么修改怎么处理呢?
预处理出每一个询问操作的前一个修改操作是第几个。
分两种情况:
1.输入中cur比target靠前,那么我们只要把从cur后面到target之间的所有修改处理一次就可以。
2.输入中cur比target靠后,那么我们需要预处理出每一个修改操作中修改之前的颜色是pre,把cur到target之间的修改处
理一次,与上面不同的是现在要把当前颜色修改成pre。
综上,只要在(curV,curU)到(targetV,targetU)转移之前对时间进行上述转移即可。
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #define M 100005 #define LL long long using namespace std; LL v[M],w[M],Ans[M],ans=0LL; int k,QQ1,dfs_clock=0,dep[M],dfn[M],be[M],b[25],f[M][22],h[M],tot=0,cnt=0,Q,QQ,n,m,vi[M],s[M],top=0,c[M],num[M],pre[M]; struct edge { int y,ne; }e[M*2]; struct Q1 { int x,y,k,pre; }q1[M],qq[M]; struct Query { int x,y,id,t; }q[M]; void r(int &tmp) { tmp=0; char ch=getchar(); for (;ch<'0'||ch>'9';ch=getchar()); for (;ch>='0'&&ch<='9';ch=getchar()) tmp=(tmp*10)+ch-'0'; } void R(LL &tmp) { tmp=0LL; char ch=getchar(); for (;ch<'0'||ch>'9';ch=getchar()); for (;ch>='0'&&ch<='9';ch=getchar()) tmp=(tmp*10)+ch-'0'; } void Addedge(int x,int y) { e[++tot].y=y; e[tot].ne=h[x]; h[x]=tot; } void dfs(int x) { dfn[x]=++dfs_clock; int bottom=top; for (int i=h[x];i;i=e[i].ne) { int y=e[i].y; if (f[x][0]==y) continue; f[y][0]=x; dep[y]=dep[x]+1; dfs(y); if (top-bottom>=k) { cnt++; while (top!=bottom) be[s[top--]]=cnt; } } s[++top]=x; } void prepare() { b[0]=1; for (int i=1;i<=16;i++) b[i]=b[i-1]<<1; for (int j=1;j<=16;j++) for (int i=1;i<=n;i++) f[i][j]=f[f[i][j-1]][j-1]; } bool cmp(Query a,Query b) { if (be[a.x]==be[b.x]) { if (be[a.y]==be[b.y]) return a.t<b.t; return be[a.y]<be[b.y]; } return be[a.x]<be[b.x]; } void Calc(int x) { if (vi[x]) ans=ans-(v[c[x]]*(w[num[c[x]]--])); else ans=ans+(v[c[x]]*(w[++num[c[x]]])); vi[x]^=1; } void Modifytime(int x,int y) { if (q[x].id<q[y].id) { for (int i=q[x].id+1;i<=q[y].id;i++) { int now=c[qq[i].x],mo=qq[i].y; if (vi[qq[i].x]) { Calc(qq[i].x); c[qq[i].x]=mo; Calc(qq[i].x); } else c[qq[i].x]=mo; } return; } for (int i=q[x].id;i>q[y].id;i--) { int now=c[qq[i].x],mo=qq[i].pre; if (vi[qq[i].x]) { Calc(qq[i].x); c[qq[i].x]=mo; Calc(qq[i].x); } else c[qq[i].x]=mo; } } void Move(int &x,int deep) { for (int i=16;i>=0;i--) if (dep[f[x][i]]>=deep) x=f[x][i]; } int Getlca(int x,int y) { if (dep[x]>dep[y]) swap(x,y); Move(y,dep[x]); if (x==y) return x; for (int i=16;i>=0;i--) if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; return f[x][0]; } void Solve(int x,int y) { while (x!=y) { if (dep[x]<dep[y]) swap(x,y); Calc(x); x=f[x][0]; } } int main() { r(n),r(m),r(QQ); k=sqrt(n); for (int i=1;i<=m;i++) R(v[i]); for (int i=1;i<=n;i++) R(w[i]); for (int i=1;i<n;i++) { int x,y; r(x),r(y); Addedge(x,y),Addedge(y,x); } dep[1]=1; dfs(1); while (top) be[s[top--]]=cnt; prepare(); for (int i=1;i<=n;i++) r(c[i]),pre[i]=c[i]; for (int i=1;i<=QQ;i++) { int t,x,y; r(t),r(x),r(y); if (!t) { QQ1++; qq[QQ1].x=x,qq[QQ1].y=y; qq[QQ1].pre=pre[x]; pre[x]=y; } else { Q++; if (dfn[x]>dfn[y]) swap(x,y); q[Q].x=x,q[Q].y=y; q[Q].id=QQ1; q[Q].t=Q; } } sort(q+1,q+1+Q,cmp); ans=0LL; q[0].id=0,q[0].x=q[0].y=1; for (int i=1;i<=Q;i++) { Modifytime(i-1,i); Solve(q[i-1].x,q[i].x); Solve(q[i-1].y,q[i].y); int a=Getlca(q[i].x,q[i].y); Calc(a); Ans[q[i].t]=ans; Calc(a); } for (int i=1;i<=Q;i++) printf("%lld\n",Ans[i]); return 0; }
相关文章推荐
- [BZOJ3052][WC2013]糖果公园-树上带修改莫队算法
- bzoj 3052: [wc2013]糖果公园 带修改莫队
- BZOJ3052: [wc2013]糖果公园
- [bzoj 3052--wc2013]糖果公园
- [BZOJ3052][WC2013]糖果公园(树上莫队修改)
- BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)
- BZOJ 3052: [wc2013]糖果公园
- bzoj3052 [wc2013]糖果公园 (树上带修改莫队)
- bzoj 3052: [wc2013]糖果公园(带修改的树上莫队)
- 【bzoj3052】[wc2013]糖果公园 带修改树上莫队
- BZOJ 3052: [wc2013]糖果公园【树上带修莫队
- BZOJ3052 [wc2013] 糖果公园 【树上莫队】
- 【BZOJ】3052: [wc2013]糖果公园
- BZOJ 3052: [wc2013]糖果公园 树上莫队
- [bzoj3052][WC2013]糖果公园
- BZOJ 3052 WC2013 糖果公园 带修改树上莫队
- [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】
- 【树上莫队】【带修莫队】bzoj3052 [wc2013]糖果公园
- [BZOJ3052]-[WC2013]糖果公园-树上带修改莫队-200题纪念!!!
- bzoj 3052 [wc2013]糖果公园