hdu5002 tree LCT
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu5002 tree LCT相关的知识,希望对你有一定的参考价值。
又是不小心打错一个字符调了一晚上。。。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000010; const int INF=1e9+10; int n,m; int pre[maxn],ch[maxn][2],rev[maxn],sz[maxn]; int val[maxn]; int fir[maxn],fircnt[maxn]; int sec[maxn],seccnt[maxn]; int add[maxn],cov[maxn]; int op,x,y,a,b,z; bool isroot(int x) { return ch[pre[x]][0]!=x&&ch[pre[x]][1]!=x; } void update_add(int x,int c) { if(!x) return; val[x]+=c; add[x]+=c; fir[x]+=c; if(seccnt[x]) sec[x]+=c; } void update_cov(int x,int c) { if(!x) return; val[x]=c; cov[x]=1; fir[x]=c;fircnt[x]=sz[x]; sec[x]=-INF;seccnt[x]=0; } void update_rev(int x) { if(!x) return; swap(ch[x][0],ch[x][1]); rev[x]^=1; } void down(int x) { if(rev[x]){ update_rev(ch[x][0]); update_rev(ch[x][1]); rev[x]=0; } if(add[x]){ update_add(ch[x][0],add[x]); update_add(ch[x][1],add[x]); add[x]=0; } if(cov[x]){ update_cov(ch[x][0],val[x]); update_cov(ch[x][1],val[x]); cov[x]=0; } } void P(int x) { if(!isroot(x)) P(pre[x]); down(x); } void solve(int x,int v,int cnt) { if(v>fir[x]) sec[x]=fir[x],seccnt[x]=fircnt[x],fir[x]=v,fircnt[x]=cnt; else if(v==fir[x]) fircnt[x]+=cnt; else if(v>sec[x]) sec[x]=v,seccnt[x]=cnt; else if(v==sec[x]) seccnt[x]+=cnt; } void up(int x) { int l=ch[x][0],r=ch[x][1]; sz[x]=sz[l]+sz[r]+1; fir[x]=-INF,fircnt[x]=0; sec[x]=-INF,seccnt[x]=0; solve(x,val[x],1); if(l) solve(x,fir[l],fircnt[l]),solve(x,sec[l],seccnt[l]); if(r) solve(x,fir[r],fircnt[r]),solve(x,sec[r],seccnt[r]); } void rot(int x,int kind) { int y=pre[x]; ch[y][kind^1]=ch[x][kind]; pre[ch[x][kind]]=y; if(!isroot(y)) ch[pre[y]][ch[pre[y]][1]==y]=x; pre[x]=pre[y]; ch[x][kind]=y; pre[y]=x; up(y); } void splay(int x) { P(x); while(!isroot(x)){ if(isroot(pre[x])) rot(x,ch[pre[x]][0]==x); else{ int y=pre[x],z=pre[y]; int kind=ch[y][0]==x,one=0; if(ch[y][0]==x&&ch[z][0]==y) one=1; if(ch[y][1]==x&&ch[z][1]==y) one=1; if(one) rot(y,kind),rot(x,kind); else rot(x,kind),rot(x,kind^1); } } up(x); } int access(int x) { int t=0; while(x){ splay(x); ch[x][1]=t; t=x;x=pre[x]; up(t); } return t; } void makeroot(int x) { access(x);splay(x);update_rev(x); } void link(int x,int y) { makeroot(x);pre[x]=y; } void cut(int x,int y) { makeroot(x);access(y);splay(y);ch[y][0]=pre[x]=0;up(y); } void Cov(int x,int y,int z) { makeroot(x);access(y);splay(y);update_cov(y,z); } void Add(int x,int y,int z) { makeroot(x);access(y);splay(y);update_add(y,z); } void query(int x,int y) { makeroot(x);access(y);splay(y); if(seccnt[y]==0) puts("ALL SAME"); else printf("%d %d\n",sec[y],seccnt[y]); } int main() { freopen("in.txt","r",stdin); int T;cin>>T;int casen=1; while(T--){ scanf("%d%d",&n,&m); REP(i,0,n) pre[i]=rev[i]=add[i]=cov[i]=0,MS0(ch[i]); REP(i,1,n){ scanf("%d",&val[i]); fir[i]=val[i];fircnt[i]=1; sec[i]=-INF,seccnt[i]=0; sz[i]=1; } REP(i,1,n-1){ scanf("%d%d",&x,&y); link(x,y); } printf("Case #%d:\n",casen++); REP(i,1,m){ scanf("%d",&op); if(op==1){ scanf("%d%d%d%d",&x,&y,&a,&b); cut(x,y); link(a,b); } else if(op==2){ scanf("%d%d%d",&x,&y,&z); Cov(x,y,z); } else if(op==3){ scanf("%d%d%d",&x,&y,&z); Add(x,y,z); } else{ scanf("%d%d",&x,&y); query(x,y); } } } return 0; }
以上是关于hdu5002 tree LCT的主要内容,如果未能解决你的问题,请参考以下文章