poj3237 Tree(树链剖分)

来源:互联网 发布:催收数据安全管理制度 编辑:程序博客网 时间:2024/04/30 02:27

边权裸题。negate操作就是区间取相反数。因此为了维护最大值,我们还要维护最小值。
tips:多组数据一定要清零啊。。。懒标记要清零啊。血的教训。

#include <cstdio>#include <cstring>#include <iostream>using namespace std;#define ll long long#define inf 0x7fffffff#define N 10010inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();    return x*f;}int n,a[N],p[N],w[N],h[N],dep[N],fa[N],son[N],size[N],top[N],id[N],dfn;struct edge{    int to,next,val;}data[N<<1];struct node{    int mx,mn,neg;}tree[N<<2];void dfs1(int x){    size[x]=1;    for(int i=h[x];i;i=data[i].next){        int y=data[i].to;        if(fa[x]==y) continue;        fa[y]=x;dep[y]=dep[x]+1;p[i>>1]=y;a[y]=data[i].val;        dfs1(y);size[x]+=size[y];        if(size[y]>size[son[x]]) son[x]=y;    }}void dfs2(int x,int tp){    id[x]=++dfn;top[x]=tp;w[dfn]=a[x];    if(son[x]) dfs2(son[x],tp);    for(int i=h[x];i;i=data[i].next){        int y=data[i].to;        if(y==fa[x]||y==son[x]) continue;        dfs2(y,y);    }}inline void pushup(int p){    tree[p].mx=max(tree[p<<1].mx,tree[p<<1|1].mx);    tree[p].mn=min(tree[p<<1].mn,tree[p<<1|1].mn);}inline void pushdown(int p){    if(!tree[p].neg) return;    tree[p<<1].neg^=1;tree[p<<1|1].neg^=1;tree[p].neg=0;    swap(tree[p<<1].mx,tree[p<<1].mn);    tree[p<<1].mx=-tree[p<<1].mx;tree[p<<1].mn=-tree[p<<1].mn;    swap(tree[p<<1|1].mx,tree[p<<1|1].mn);    tree[p<<1|1].mx=-tree[p<<1|1].mx;tree[p<<1|1].mn=-tree[p<<1|1].mn;}void build(int p,int l,int r){    tree[p].neg=0;    if(l==r){tree[p].mx=tree[p].mn=w[l];return;}    int mid=l+r>>1;    build(p<<1,l,mid);build(p<<1|1,mid+1,r);    pushup(p);}void negat(int p,int l,int r,int x,int y){    if(x<=l&&r<=y){        tree[p].neg^=1;swap(tree[p].mx,tree[p].mn);        tree[p].mx=-tree[p].mx;tree[p].mn=-tree[p].mn;        return;    }    int mid=l+r>>1;pushdown(p);    if(x<=mid) negat(p<<1,l,mid,x,y);    if(y>mid) negat(p<<1|1,mid+1,r,x,y);    pushup(p);}void change(int p,int l,int r,int x,int val){    if(l==r){tree[p].mx=tree[p].mn=val;return;}    int mid=l+r>>1;pushdown(p);    if(x<=mid) change(p<<1,l,mid,x,val);    else change(p<<1|1,mid+1,r,x,val);    pushup(p);}int qmax(int p,int l,int r,int x,int y){    if(x<=l&&r<=y){return tree[p].mx;}    int mid=l+r>>1,res=-inf;pushdown(p);    if(x<=mid) res=max(res,qmax(p<<1,l,mid,x,y));    if(y>mid) res=max(res,qmax(p<<1|1,mid+1,r,x,y));    return res;}void donegate(int x,int y){    while(top[x]!=top[y]){        if(dep[top[x]]<dep[top[y]]) swap(x,y);        negat(1,1,n,id[top[x]],id[x]);        x=fa[top[x]];    }    if(id[x]>id[y]) swap(x,y);if(id[x]==id[y]) return;    negat(1,1,n,id[x]+1,id[y]);}int domax(int x,int y){    int res=-inf;    while(top[x]!=top[y]){        if(dep[top[x]]<dep[top[y]]) swap(x,y);        res=max(res,qmax(1,1,n,id[top[x]],id[x]));        x=fa[top[x]];    }    if(id[x]>id[y]) swap(x,y);if(id[x]==id[y]) return res;    return max(res,qmax(1,1,n,id[x]+1,id[y]));}int main(){//  freopen("a.in","r",stdin);    int tt=read();    while(tt--){        memset(fa,0,sizeof(fa));        memset(son,0,sizeof(son));        memset(h,0,sizeof(h));dfn=0;        n=read();        for(int i=1;i<n;++i){            int x=read(),y=read(),v=read();            data[i<<1].to=y;data[i<<1].next=h[x];h[x]=i<<1;data[i<<1].val=v;            data[i<<1|1].to=x;data[i<<1|1].next=h[y];h[y]=i<<1|1;data[i<<1|1].val=v;        }        dep[1]=1;dfs1(1);dfs2(1,1);build(1,1,n);        while(1){            char op[10];scanf("%s",op);            if(op[0]=='D') break;int x=read(),y=read();            if(op[0]=='C') change(1,1,n,id[p[x]],y);            if(op[0]=='N') donegate(x,y);            if(op[0]=='Q') printf("%d\n",domax(x,y));        }    }    return 0;}