bzoj 2959: 长跑 lct

来源:互联网 发布:数据质量分析方法 编辑:程序博客网 时间:2024/04/28 07:07

       显然,如果没有环的话,走的就是两点之间的唯一路径。直接用lct维护即可。

       但是现在有环,显然可以把环缩到一个点,那么用并查集维护一下即可。剩下的使用lct即可。

       嘴巴AC还是很简单的。。。

AC代码如下:

#include<iostream>#include<cstdio>#include<cstring>#define N 150005using namespace std;int n,m,a[N],c[N][2],fa[N],sum[N],val[N];bool rev[N];int read(){int x=0; char ch=getchar();while (ch<'0' || ch>'9') ch=getchar();while (ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }return x;}struct frt{int anc[N];void pfs(){ int i; for (i=1; i<=n; i++) anc[i]=i; }int getanc(int x){return (x==anc[x])?x:anc[x]=getanc(anc[x]);}}f1,f2;bool isrt(int x){ return c[fa[x]][0]!=x && c[fa[x]][1]!=x; }void maintain(int x){sum[x]=val[x]+sum[c[x][0]]+sum[c[x][1]];}void dn(int x){if (x && rev[x]){rev[c[x][0]]^=1; rev[c[x][1]]^=1;swap(c[x][0],c[x][1]); rev[x]=0;}}void pushdown(int x){if (!isrt(x)) pushdown(fa[x]); dn(x);}void rotate(int x){int y=fa[x],z=fa[y],l=(c[y][0]==x)?0:1,r=l^1;if (!isrt(y))if (c[z][0]==y) c[z][0]=x; else c[z][1]=x;fa[x]=z; fa[y]=x; fa[c[x][r]]=y;c[y][l]=c[x][r]; c[x][r]=y;maintain(y); maintain(x);}void splay(int x){pushdown(x); int y,z;while (!isrt(x)){y=fa[x]; z=fa[y];if (!isrt(y))if ((c[y][0]==x)^(c[z][0]==y)) rotate(x); else rotate(y);rotate(x);}}void accs(int x){int y=0;for (; x; y=x,x=f2.getanc(fa[x])){splay(x); c[x][1]=y; fa[y]=x; maintain(x);}}void makert(int x){ accs(x); splay(x); rev[x]^=1; }void link(int x,int y){ makert(x); fa[x]=y; }void ins(int x,int y){x=f2.getanc(x); splay(x);val[x]+=y; maintain(x);}void merge(int x,int y){dn(x); f2.anc[x]=y;if (x!=y) val[y]+=val[x];if (c[x][0]) merge(c[x][0],y); if (c[x][1]) merge(c[x][1],y);c[x][0]=c[x][1]=0;}int main(){n=read(); m=read(); int i,x,y,u,v,k;f1.pfs(); f2.pfs();for (i=1; i<=n; i++){a[i]=read(); ins(i,a[i]);}while (m--){k=read(); x=read(); y=read();if (k==1){x=f2.getanc(x); y=f2.getanc(y);if (x!=y){u=f1.getanc(x); v=f1.getanc(y);if (u!=v){ link(x,y); f1.anc[u]=v; } else{makert(x); accs(y); splay(y);merge(y,y);}}} else if (k==2){ins(x,y-a[x]); a[x]=y;} else{x=f2.getanc(x); y=f2.getanc(y);u=f1.getanc(x); v=f1.getanc(y);if (u!=v) puts("-1"); else{makert(x); accs(y); splay(y);printf("%d\n",sum[y]);}}}return 0;}


by lych

2016.4.13

0 0