uoj#58./bzoj3052 【WC2013】糖果公园 //树上带修改莫队
2018-01-17 22:37
453 查看
uoj#58. 【WC2013】糖果公园
题意
有一棵N(<=1e5)个点的树,每个点对应M(<=1e5)种糖果中的一种。一条路径的权值定义为∑i(Vi∗∑tij=1Wj),其中i为路径中出现的不同种类糖果,ti为第i种糖果的出现次数,V和W给定。
Q(<=1e5)次操作,每次操作修改一个点对应的糖果种类,或询问路径(u,v)的权值。
题解
半年前写了一半,然而代码弄丢了。树上莫队和带修改莫队放一起,算是比较模板的题?
跑得太慢了,不好意思写题解,就放个代码吧。
代码
#include<bits/stdc++.h> #define N 100005 #define L 18 #define Y no[i] #define X mx[op] using namespace std; typedef long long ll; ll ans ,s,ss ; bool vis ; char ch; inline void rd(int &x) { x=0; do ch=getchar(); while(ch<'0'||ch>'9'); do x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); while(ch>='0'&&ch<='9'); } int n,m,q,sqr,tp,mx ,my ,pre , ql ,qr ,qx ,no ,mt,qt,t , V ,W ,c ,b ,f [L],dep , to[N<<1],hd[N<<1],lk ,cnt; inline void add(int u,int v) {to[++cnt]=v,hd[cnt]=lk[u],lk[u]=cnt;} void dfs(int x) { dep[x]=dep[f[x][0]]+1; b[x]=tp++/sqr; for(int i=1;f[x][i-1];i++) f[x][i]=f[f[x][i-1]][i-1]; for(int k,i=lk[x];i;i=hd[i]) if(!dep[k=to[i]]) f[k][0]=x,dep[k]=dep[x]+1,dfs(k); } bool cmp(int x,int y) { return (b[ql[x]]^b[ql[y]])?b[ql[x]]<b[ql[y]]: ((b[qr[x]]^b[qr[y]])?b[qr[x]]<b[qr[y]]:qx[x]<qx[y]); } inline void ins(int x,int v) { s-=ss[x]; if(v>0)ss[x]+=(ll)V[x]*W[t[x]+1]; else ss[x]-=(ll)V[x]*W[t[x]]; t[x]+=v,s+=ss[x]; } inline void mdf(int x) {ins(c[x],(vis[x]^=1)?1:-1);} inline void trans(int x,int y) { if(dep[x]<dep[y])swap(x,y); while(dep[x]>dep[y]) mdf(x),x=f[x][0]; while(x^y)mdf(x),mdf(y),x=f[x][0],y=f[y][0]; } int op,u,v,x,y; int main() { rd(n),rd(m),rd(q); for(int i=1;i<=m;rd(V[i++])); for(int i=1;i<=n;rd(W[i++])); for(int i=1;i<n;i++) rd(u),rd(v),add(u,v),add(v,u); for(int i=1;i<=n;rd(c[i++])); while(sqr*sqr*sqr<n)sqr++; sqr=n/sqr; dfs(1),tp=0; for(int i=1;i<=q;i++) { rd(op); if(op) { rd(ql[qt]),rd(qr[qt]); if(b[ql[qt]]>b[qr[qt]]) swap(ql[qt],qr[qt]); no[qt]=qt,qx[qt++]=mt; } else rd(u),rd(my[mt]), pre[mt]=c[mx[mt]=u], c[u]=my[mt++]; } sort(no,no+qt,cmp); u=v=1,op=mt; for(int i=0;i<qt;i++) { trans(u,ql[Y]),u=ql[Y]; trans(v,qr[Y]),v=qr[Y]; while(op<qx[Y]) { if(vis[X]) ins(c[X],-1),ins(my[op],1); c[X]=my[op],op++; } while(op>qx[Y]) { op--; if(vis[X]) ins(c[X],-1),ins(pre[op],1); c[X]=pre[op]; } x=u,y=v; if(dep[y]>dep[x])swap(x,y); for(int j=L-1;dep[x]^dep[y];j--) if(dep[f[x][j]]>=dep[y]) x=f[x][j]; for(int j=L-1;j>=0;j--) if(f[x][j]^f[y][j]) x=f[x][j],y=f[y][j]; if(x^y)x=f[x][0]; mdf(x);ans[Y]=s;mdf(x); } for(int i=0;i<qt;i++) printf("%lld\n",ans[i]); }
相关文章推荐
- bzoj3052 [wc2013]糖果公园 (树上带修改莫队)
- [BZOJ3052]-[WC2013]糖果公园-树上带修改莫队-200题纪念!!!
- BZOJ.3052.[WC2013]糖果公园(树上莫队 带修改莫队)
- [BZOJ3052][wc2013]糖果公园(树上带修改莫队)
- bzoj3052 [wc2013]糖果公园(树上莫队,带修改)
- bzoj 3052: [wc2013]糖果公园【树上带修改莫队】
- bzoj 3052: [wc2013]糖果公园(带修改的树上莫队)
- BZOJ 3052 WC2013 糖果公园 带修改树上莫队
- 【BZOJ3052】[wc2013]糖果公园 带修改的树上莫队
- 【bzoj3052】[wc2013]糖果公园 带修改树上莫队
- [BZOJ3052][WC2013]糖果公园(树上莫队修改)
- [BZOJ 3052][wc2013]糖果公园:树上带修改莫队
- [树上带修莫队] BZOJ3052: [WC2013]糖果公园
- BZOJ 3052: [wc2013]糖果公园 | 树上莫队
- BZOJ 3052 [wc2013]糖果公园 树上莫队
- 【BZOJ3052】【UOJ#58】【WC2013】糖果公园(树上莫队)
- [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】
- [BZOJ3052][WC2013]糖果公园-树上带修改莫队算法
- 【树上莫队】【带修莫队】bzoj3052 [wc2013]糖果公园
- BZOJ 3052: [wc2013]糖果公园 树上莫队