支持:
1.添加边 x,y
2.删边 x,y
3.对于路径x,y上的所有节点的值加上w
4.询问路径x,y上的所有节点的最大权值
分析:
裸的lct...
rev忘了清零死循环了两小时。。。
1:就是link操作
2:就是cut操作
3:维护多一个mx域,mx[x]表示在splay中以节点x为根的子树的最大点权,每次修改时,把x置为splay的根,打通y到x的路径,把y splay到根,那么,直接对y节点的lazy标记加上为w即可。
4:同3操作,把x置为splay的根,打通y到x的路径,把y splay到根,那么,y子树所对应的节点就是路径x到y的所有节点。
另外,题目貌似描述有点问题,不光是询问非法输出-1,是指操作如果是非法就输出-1....
#include <set> #include <map> #include <list> #include <cmath> #include <queue> #include <stack> #include <string> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; #define debug puts("here") #define rep(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define REP(i,a,b) for(int i=a;i<=b;i++) #define foreach(i,vec) for(unsigned i=0;i<vec.size();i++) #define pb push_back #define RD(n) scanf("%d",&n) #define RD2(x,y) scanf("%d%d",&x,&y) #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w) #define All(vec) vec.begin(),vec.end() #define MP make_pair #define PII pair<int,int> #define PQ priority_queue #define cmax(x,y) x = max(x,y) #define cmin(x,y) x = min(x,y) #define Clear(x) memset(x,0,sizeof(x)) /* #pragma comment(linker, "/STACK:1024000000,1024000000") int size = 256 << 20; // 256MB char *p = (char*)malloc(size) + size; __asm__("movl %0, %%esp " :: "r"(p) ); */ /******** program ********************/ const int MAXN = 3e5+5; // 外挂 char op; inline void Int(int &x){ while( !isdigit(op=getchar()) ); x = op-'0'; while(isdigit(op=getchar())) x = x*10+op-'0'; } struct LCT{ int ch[MAXN][2],fa[MAXN]; int lz[MAXN],mx[MAXN],val[MAXN]; bool rev[MAXN]; int sta[MAXN],top; inline void init(){ Clear(ch); Clear(fa); Clear(lz); Clear(rev); mx[0] = 0; } inline void modify(int x,int d){ // 单点增加lazy标记 if(!x)return; lz[x] += d; mx[x] += d; val[x] += d; } inline void clear(int x){ if(!x)return; if(rev[x]){ if(ch[x][0])rev[ch[x][0]] ^= 1; if(ch[x][1])rev[ch[x][1]] ^= 1; swap(ch[x][0],ch[x][1]); rev[x] = 0; } if(lz[x]){ modify(ch[x][0],lz[x]); modify(ch[x][1],lz[x]); lz[x] = 0; } } inline void update(int x){ if(!x)return; mx[x] = max( val[x],max(mx[ch[x][0]],mx[ch[x][1]]) ); } inline bool isRoot(int x){ return !x || !( (ch[ fa[x] ][0]==x) || (ch[ fa[x] ][1]==x) ); } inline bool sgn(int x){ return ch[ fa[x] ][1]==x; } inline void setc(int y,int d,int x){ ch[y][d] = x; fa[x] = y; } inline void rot(int x){ int y = fa[x] , z = fa[y] , d = sgn(x)^1; setc(y,d^1,ch[x][d]); if(isRoot(y)) fa[x] = fa[y]; else setc(z,sgn(y),x); setc(x,d,y); update(y); } inline void splay(int x){ if(!x)return; top = 0; sta[++top] = x; for(int y=x;!isRoot(y);y=fa[y]) sta[++top] = fa[y]; while(top)clear(sta[top--]); while(!isRoot(x)){ if(isRoot(fa[x]))rot(x); else{ sgn(x)==sgn(fa[x]) ? rot(fa[x]) : rot(x); rot(x); } } update(x); } inline int access(int x){ int y = 0; for(;x;x=fa[y = x]){ splay(x); ch[x][1] = y; update(x); } return y; } inline void mRoot(int x){ rev[ access(x) ] ^= 1; splay(x); } inline int getRoot(int x){ x = access(x); while(ch[x][0]){ x = ch[x][0]; clear(x); } return x; } inline bool jud(int x,int y){// ok return getRoot(x)==getRoot(y); } inline void link(int x,int y){ if(jud(x,y)){ puts("-1"); return; } mRoot(x); fa[x] = y; //access(x); } inline void cut(int x,int y){ if(x==y||!jud(x,y)){ puts("-1"); return; } mRoot(x); access(y); splay(y); fa[ ch[y][0] ] = 0; ch[y][0] = 0; update(y); } inline void modify(int x,int y,int c){ if(!jud(x,y)){ puts("-1"); return; } mRoot(x); access(y); splay(y); modify(y,c); clear(y); } inline int ask(int x,int y){ if(!jud(x,y)) return -1; mRoot(x); access(y); splay(y); return mx[y]; } }lct; struct Edge{ int y,next; }edge[MAXN<<1]; int po[MAXN],tol; inline void add(int x,int y){ edge[++tol].y = y; edge[tol].next = po[x]; po[x] = tol; } void dfs(int x,int pa){ lct.fa[x] = pa; for(int i=po[x];i;i=edge[i].next) if(edge[i].y!=pa) dfs(edge[i].y,x); } int main(){ #ifndef ONLINE_JUDGE freopen("sum.in","r",stdin); //freopen("sum.out","w",stdout); #endif int x,y,w,n,m,op; while(~RD(n)){ lct.init(); Clear(po); tol = 0; REP(i,2,n){ Int(x);Int(y); add(x,y); add(y,x); } dfs(1,0); rep1(i,n){ RD(lct.val[i]); lct.mx[i] = lct.val[i]; } RD(m); while(m--){ Int(op); if(op==1){ Int(x);Int(y); lct.link(x,y); }else if(op==2){ Int(x);Int(y); lct.cut(x,y); }else if(op==3){ Int(w);Int(x);Int(y); lct.modify(x,y,w); }else{ Int(x);Int(y); printf("%d ",lct.ask(x,y)); } } puts(""); } return 0; }