poj3237 树链剖分

来源:互联网 发布:低音炮蓝牙音响淘宝 编辑:程序博客网 时间:2024/05/16 16:56
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;#define N 10010#define INF 0x7f7f7f7f#define MAX(a,b) (((a)>(b))?(a):(b))#define MIN(a,b) (((a)<(b))?(a):(b))struct hh{int v,w,next,num;}edges[N<<1];struct segtree{int maxx,minn,delta;}tree[N<<2];int T,n,son[N],dep[N],fa[N],val[N],hash[N],from[N],size[N],top[N],point[N],a,b,tid[N],num[N],en,end;char str[100];int flag;inline void init(){memset(point,0xff,sizeof(point));en=-1;end=0;a=b=0;}inline void addedge(int u,int v,int w,int num){edges[++en].next=point[u];point[u]=en;edges[en].v=v;edges[en].w=w;edges[en].num=num;edges[++en].next=point[v];point[v]=en;edges[en].v=u;edges[en].w=w;edges[en].num=num;}inline void dfs(int x){size[x]=1;son[x]=0;for(int i=point[x];i!=-1;i=edges[i].next)if(edges[i].v!=fa[x]){fa[edges[i].v]=x;dep[edges[i].v]=dep[x]+1;from[edges[i].v]=i;dfs(edges[i].v);if(size[edges[i].v]>size[son[x]])son[x]=edges[i].v;size[x]+=size[edges[i].v];}}inline void make(int x,int anc){tid[x]=++end;val[end]=edges[from[x]].w;hash[edges[from[x]].num]=end;top[x]=anc;if(son[x]!=0)make(son[x],anc);for(int i=point[x];i!=-1;i=edges[i].next)if(edges[i].v!=fa[x]&&edges[i].v!=son[x])make(edges[i].v,edges[i].v);}inline void negative(int x){int tmp=tree[x].maxx;tree[x].maxx=-tree[x].minn;tree[x].minn=-tmp;}inline void push_up(int x){tree[x].maxx=MAX(tree[x<<1].maxx,tree[x<<1^1].maxx);tree[x].minn=MIN(tree[x<<1].minn,tree[x<<1^1].minn);}inline void push_down(int x){if(tree[x].delta){tree[x<<1].delta^=1;tree[x<<1^1].delta^=1;negative(x<<1);negative(x<<1^1);tree[x].delta=0;}}inline void build(int x,int l,int r){if(l==r){tree[x].maxx=tree[x].minn=val[l];tree[x].delta=0;return;}int mid=l+r>>1;build(x<<1,l,mid);build(x<<1^1,mid+1,r);push_up(x);tree[x].delta=0;}inline void update(int x,int l,int r,int left,int right,int delta){if(l>=left&&r<=right){if(!flag)tree[x].maxx=tree[x].minn=delta;if(flag){tree[x].delta^=1;negative(x);}return;}int mid=l+r>>1;push_down(x);if(left<=mid)update(x<<1,l,mid,left,right,delta);if(right>mid)update(x<<1^1,mid+1,r,left,right,delta);push_up(x);}inline int query(int x,int l,int r,int left,int right){if(l>=left&&r<=right)return tree[x].maxx;int mid=l+r>>1,tmp1=-INF,tmp2=-INF;push_down(x);if(left<=mid)tmp1=query(x<<1,l,mid,left,right);if(right>mid)tmp2=query(x<<1^1,mid+1,r,left,right);push_up(x);return MAX(tmp1,tmp2);}inline void change(int x,int y){int f1=top[x],f2=top[y];while(f1!=f2){if(dep[f1]<dep[f2]){swap(f1,f2);swap(x,y);}update(1,1,end,tid[f1],tid[x],0);x=fa[f1];f1=top[x];}if(x==y)return;if(dep[x]>dep[y])swap(x,y);update(1,1,end,tid[son[x]],tid[y],0);}inline int ask(int x,int y){if(x==y)return 0;int f1=top[x],f2=top[y],res=-INF,tmp;while(f1!=f2){if(dep[f1]<dep[f2]){swap(x,y);swap(f1,f2);}tmp=query(1,1,end,tid[f1],tid[x]);res=MAX(res,tmp);x=fa[f1];f1=top[x];}if(x==y)return res;if(dep[x]>dep[y])swap(x,y);tmp=query(1,1,end,tid[son[x]],tid[y]);return MAX(res,tmp);}int main(){scanf("%d",&T);while(T--){scanf("%d",&n);init();for(int i=1;i<n;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);addedge(u,v,w,i);}dep[1]=0;dfs(1);make(1,1);build(1,1,end);while(1){scanf(" %s",str);if(str[0]=='D')break;scanf("%d%d",&a,&b);if(str[0]=='C')flag=0,update(1,1,end,hash[a],hash[a],b);if(str[0]=='Q')printf("%d\n",ask(a,b));if(str[0]=='N')flag=1,change(a,b);}}return 0;}


                                             
0 0