POJ 3237 Tree(树链剖分 线段树区间标记)

来源:互联网 发布:杭州龙蛇网络 编辑:程序博客网 时间:2024/05/21 10:47

题意:

一棵树

三种操作

1.改变某条边的权值

2.a到b的路径取反

3,询问a到b路径上的最大值


分析:

树链剖分

线段树维护最大最小值,标记取反

代码量大

#include<cstring>#include<string>#include<iostream>#include<queue>#include<cstdio>#include<algorithm>#include<map>#include<cstdlib>#include<cmath>#include<vector>//#pragma comment(linker, "/STACK:1024000000,1024000000");using namespace std;#define INF 0x3f3f3f3f#define maxn 20004int x[maxn],y[maxn];int fir[maxn],nex[maxn],v[maxn],w[maxn],e_max;int son[maxn],fa[maxn],siz[maxn],deep[maxn],top[maxn],pos[maxn],tot;int val1[maxn],val2[maxn],mi[4*maxn],mx[4*maxn],tag[4*maxn];void init_(){    val1[0]=val1[1]=0;    memset(fir,-1,sizeof fir);    memset(son,-1,sizeof son);    memset(siz,0,sizeof siz);    e_max=0;    tot=1;}void add_edge(int s,int t,int c){    int e=e_max++;    v[e]=t;    w[e]=c;    nex[e]=fir[s];    fir[s]=e;}void dfs1(int k,int pre,int d){    deep[k]=d;    siz[k]++;    fa[k]=pre;    for(int i=fir[k];~i;i=nex[i])    {        int e=v[i];        if(e!=pre)        {            val1[e]=w[i];            dfs1(e,k,d+1);            siz[k]+=siz[e];            if(son[k]==-1||siz[son[k]]<siz[e]) son[k]=e;        }    }}void dfs2(int k,int sp){    top[k]=sp;    pos[k]=tot++;    val2[pos[k]]=val1[k];    if(son[k]==-1) return;    dfs2(son[k],sp);    for(int i=fir[k];~i;i=nex[i])    {        int e=v[i];        if(e!=fa[k]&&e!=son[k])        {            dfs2(e,e);        }    }}void pushup(int k){    mx[k]=max(mx[k<<1],mx[k<<1|1]);    mi[k]=min(mi[k<<1],mi[k<<1|1]);}void pushdown(int k){    if(!tag[k]) return ;    tag[k<<1]^=1;    tag[k<<1|1]^=1;    swap(mx[k<<1],mi[k<<1]);    mx[k<<1]=-mx[k<<1];    mi[k<<1]=-mi[k<<1];    swap(mx[k<<1|1],mi[k<<1|1]);    mx[k<<1|1]=-mx[k<<1|1];    mi[k<<1|1]=-mi[k<<1|1];    tag[k]=0;}void init(int l,int r,int k){    tag[k]=0;    if(l==r)    {        mi[k]=mx[k]=val2[l];        return ;    }    int mid=l+r>>1;    init(l,mid,k<<1);    init(mid+1,r,k<<1|1);    pushup(k);}void update1(int d,int s,int l,int r,int k){    if(s==l&&s==r)    {        mi[k]=mx[k]=d;        return ;    }    pushdown(k);    int mid=l+r>>1;    if(s<=mid) update1(d,s,l,mid,k<<1);    else update1(d,s,mid+1,r,k<<1|1);    pushup(k);}void update2(int d,int s,int t,int l,int r,int k){    if(s==l&&r==t)    {        tag[k]^=d;        swap(mx[k],mi[k]);        mx[k]=-mx[k];        mi[k]=-mi[k];        return ;    }    pushdown(k);    int mid=l+r>>1;    if(t<=mid) update2(d,s,t,l,mid,k<<1);    else if(s>mid) update2(d,s,t,mid+1,r,k<<1|1);    else    {        update2(d,s,mid,l,mid,k<<1);        update2(d,mid+1,t,mid+1,r,k<<1|1);    }    pushup(k);}int query(int s,int t,int l,int r,int k){    if(s==l&&r==t)    {        return mx[k];    }    pushdown(k);    int mid=l+r>>1;    if(t<=mid) return query(s,t,l,mid,k<<1);    else if(s>mid) return query(s,t,mid+1,r,k<<1|1);    else return max(query(s,mid,l,mid,k<<1),query(mid+1,t,mid+1,r,k<<1|1));}void Query(int s,int t){    if(s==t)    {        printf("0\n");        return ;    }    int ans=-INF;    int f1=top[s],f2=top[t];    while(f1!=f2)    {        if(deep[f1]<deep[f2]) swap(f1,f2),swap(s,t);        ans=max(ans,query(pos[f1],pos[s],1,tot-1,1));        s=fa[f1];        f1=top[s];    }    if(s==t)    {        printf("%d\n",ans);        return ;    }    if(deep[s]>deep[t]) swap(s,t);    ans=max(ans,query(pos[s]+1,pos[t],1,tot-1,1));    printf("%d\n",ans);}void Change(int s,int t){    int f1=top[s],f2=top[t];    while(f1!=f2)    {        if(deep[f1]<deep[f2]) swap(f1,f2),swap(s,t);        update2(1,pos[f1],pos[s],1,tot-1,1);        s=fa[f1];        f1=top[s];    }    if(s==t) return ;    if(deep[s]>deep[t]) swap(s,t);    update2(1,pos[s]+1,pos[t],1,tot-1,1);}int main(){    int T;    scanf("%d",&T);    while(T--)    {        init_();        int n;        scanf("%d",&n);        for(int i=1;i<n;i++)        {            int c;            scanf("%d%d%d",&x[i],&y[i],&c);            add_edge(x[i],y[i],c);            add_edge(y[i],x[i],c);        }        dfs1(1,-1,1);        dfs2(1,1);        init(1,tot-1,1);        char s[10];        while(scanf("%s",s)!=EOF&&strcmp(s,"DONE"))        {            if(!strcmp(s,"QUERY"))            {                int l,r;                scanf("%d%d",&l,&r);                Query(l,r);            }            else if(!strcmp(s,"CHANGE"))            {                int i,ti;                scanf("%d%d",&i,&ti);                if(deep[x[i]]<deep[y[i]]) swap(x[i],y[i]);                update1(ti,pos[x[i]],1,tot-1,1);            }            else            {                int l,r;                scanf("%d%d",&l,&r);                Change(l,r);            }        }    }    return 0;}




0 0
原创粉丝点击