POJ 3237 Tree 树链剖分 边权

来源:互联网 发布:宏杰软件 编辑:程序博客网 时间:2024/06/04 19:39

这个题目比SPOJ的QTree多了一个u->v内所有边的边权都变为相反数的操作,其他的都是类似的,单点更新,区间查询最大值。

因为有了取反操作,因为最小值的相反数是最大值,最大值的相反数是最小值..所以线段树要多记录一个最小值...

用这个题的代码我过了SPOJ那个QTREE,当时那个RE错误..并不懂是怎么犯的..

#include<iostream>#include<algorithm>#include<cstdlib>#include<cstring>#include<cmath>#include<cstdio>using namespace std;#define MAXN 10010struct edge{    int u,v,next;}edge[MAXN*2];int son[MAXN],fa[MAXN],top[MAXN],num[MAXN];int dep[MAXN],p[MAXN],head[MAXN];int t,pos;void inti(){    t=0;    memset(head,-1,sizeof(head));    pos=1;    memset(son,-1,sizeof(son));}void add(int u,int v){    edge[t].v=v;    edge[t].next=head[u];    head[u]=t++;}void dfs1(int u,int d){    dep[u]=d;    num[u]=1;    for(int i=head[u];i!=-1;i=edge[i].next)    {        int v=edge[i].v;        if(v!=fa[u])        {            fa[v]=u;            dfs1(v,d+1);            num[u]+=num[v];            if(son[u]==-1||num[v]>num[son[u]])                son[u]=v;        }    }}void dfs2(int u,int sp){    top[u]=sp;    p[u]=pos++;    if(son[u]!=-1)        dfs2(son[u],sp);    for(int i=head[u];i!=-1;i=edge[i].next)    {        int v=edge[i].v;        if(v!=son[u]&&v!=fa[u])            dfs2(v,v);    }}struct node{    int l,r,ma,mi,ne;}data[MAXN*4];void build(int l,int r,int k){    data[k].l=l;    data[k].r=r;    data[k].ma=data[k].mi=0;    data[k].ne=0;    if(l==r) return ;    int mid=(l+r)/2;    build(l,mid,k*2);    build(mid+1,r,k*2+1);}void pushup(int k){    data[k].ma=max(data[k*2].ma,data[k*2+1].ma);    data[k].mi=min(data[k*2].mi,data[k*2+1].mi);}void pushdown(int k){    if(data[k].l==data[k].r) return ;    if(data[k].ne)    {        data[k*2].ma=-data[k*2].ma;        data[k*2].mi=-data[k*2].mi;        swap(data[k*2].ma,data[k*2].mi);        data[k*2+1].ma=-data[k*2+1].ma;        data[k*2+1].mi=-data[k*2+1].mi;        swap(data[k*2+1].ma,data[k*2+1].mi);        data[k*2].ne^=1;        data[k*2+1].ne^=1;        data[k].ne=0;    }}void updata(int x,int val,int k){    if(data[k].l==data[k].r&&data[k].l==x)    {        data[k].ma=data[k].mi=val;        data[k].ne=0;        return ;    }    pushdown(k);    int mid=(data[k].l+data[k].r)/2;    if(x<=mid)        updata(x,val,k*2);    else        updata(x,val,k*2+1);    pushup(k);}void neupdata(int l,int r,int k){    if(data[k].l==l&&data[k].r==r)    {        data[k].ma=-data[k].ma;        data[k].mi=-data[k].mi;        swap(data[k].ma,data[k].mi);        data[k].ne^=1;        return ;    }    pushdown(k);    int mid=(data[k].l+data[k].r)/2;    if(r<=mid) neupdata(l,r,k*2);    else if(l>mid) neupdata(l,r,k*2+1);    else    {        neupdata(l,mid,k*2);        neupdata(mid+1,r,k*2+1);    }    pushup(k);}int query(int l,int r,int k){    if(data[k].l==l&&data[k].r==r)        return data[k].ma;    pushdown(k);    int mid=(data[k].l+data[k].r)/2;    if(r<=mid)        return query(l,r,k*2);    else if(l>mid)        return query(l,r,k*2+1);    else        return max(query(l,mid,k*2),query(mid+1,r,k*2+1));}int findmax(int u,int v){    int f1=top[u];    int f2=top[v];    int ans=-100000000;;    while(f1!=f2)    {        if(dep[f1]<dep[f2])        {            swap(f1,f2);            swap(u,v);        }        ans=max(ans,query(p[f1],p[u],1));        u=fa[f1];        f1=top[u];    }    if(u==v) return ans;    if(dep[u]>dep[v]) swap(u,v);    return  max(ans,query(p[son[u]],p[v],1));}void negat(int u,int v){    int f1=top[u];    int f2=top[v];    while(f1!=f2)    {        if(dep[f1]<dep[f2])        {            swap(f1,f2);            swap(u,v);        }        neupdata(p[f1],p[u],1);        u=fa[f1];        f1=top[u];    }    if(u==v) return ;    if(dep[u]>dep[v]) swap(u,v);    neupdata(p[son[u]],p[v],1);}int e[MAXN][3];int main(){    int T;    scanf("%d",&T);    while(T--)    {        int n;        inti();        scanf("%d",&n);        for(int i=1;i<n;i++)        {            scanf("%d %d %d",&e[i][0],&e[i][1],&e[i][2]);            add(e[i][0],e[i][1]);            add(e[i][1],e[i][0]);        }        dfs1(1,0);        dfs2(1,1);        build(1,pos,1);        for(int i=1;i<n;i++)        {            if(dep[e[i][0]]>dep[e[i][1]])                swap(e[i][0],e[i][1]);            updata(p[e[i][1]],e[i][2],1);        }        char op[10];        int u,v;        while(scanf("%s",op)==1)        {            if(op[0]=='D')            break;            scanf("%d %d",&u,&v);            if(op[0]=='Q')                printf("%d\n",findmax(u,v));            else if(op[0]=='C')                updata(p[e[u][1]],v,1);            else                negat(u,v);        }    }    return 0;}


0 0
原创粉丝点击