poj 3237 树链剖分(区间更新,区间查询)

来源:互联网 发布:美国下饺子知乎 编辑:程序博客网 时间:2024/06/07 04:46

http://poj.org/problem?id=3237

Description

You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 through N − 1. Each edge is associated with a weight. Then you are to execute a series of instructions on the tree. The instructions can be one of the following forms:

CHANGE i vChange the weight of the ith edge to vNEGATE a bNegate the weight of every edge on the path from a to bQUERY a bFind the maximum weight of edges on the path from a to b

Input

The input contains multiple test cases. The first line of input contains an integer t (t ≤ 20), the number of test cases. Then follow the test cases.

Each test case is preceded by an empty line. The first nonempty line of its contains N (N ≤ 10,000). The next N − 1 lines each contains three integers ab and c, describing an edge connecting nodes a and bwith weight c. The edges are numbered in the order they appear in the input. Below them are the instructions, each sticking to the specification above. A lines with the word “DONE” ends the test case.

Output

For each “QUERY” instruction, output the result on a separate line.

Sample Input

131 2 12 3 2QUERY 1 2CHANGE 1 3QUERY 1 2DONE

Sample Output

13
/**poj 3237 树链剖分(区间更新,区间查询)题目大意:给定一棵树,动态修改:1.对于给定的两点之间的所有边权取相反数,2对于给定边修改值,动态查询:指定两点间边权最大值解题思路:树链剖分。在线段树区间维护的时候要维护一个最大值和一个最小值,因为一翻转二者就会相互装换*/#include <string.h>#include <stdio.h>#include <algorithm>#include <iostream>using namespace std;typedef long long LL;const int maxn=10005;int fa[maxn],dep[maxn],son[maxn],d[maxn][3],num[maxn],top[maxn],siz[maxn];int n,z,maxx[maxn*4],minn[maxn*4],col[maxn*4];int head[maxn],ip;void init(){    memset(col,0,sizeof(col));    memset(head,-1,sizeof(head));    ip=0;}struct note{    int v,w,next;} edge[maxn*4];void addedge(int u,int v,int w){    edge[ip].v=v,edge[ip].w=w,edge[ip].next=head[u],head[u]=ip++;}void dfs(int u,int pre){    son[u]=0,siz[u]=1,dep[u]=dep[pre]+1,fa[u]=pre;    for(int i=head[u]; i!=-1; i=edge[i].next)    {        int v=edge[i].v;        if(v==pre)continue;        dfs(v,u);        siz[u]+=siz[v];        if(siz[son[u]]<siz[v])        {            son[u]=v;        }    }    ///printf("%d son fa dep %d %d %d\n",u,son[u],fa[u],dep[u]);}void init_que(int u,int tp){    num[u]=++z,top[u]=tp;    if(son[u])    {        init_que(son[u],tp);    }    for(int i=head[u]; i!=-1; i=edge[i].next)    {        int v=edge[i].v;        if(v==fa[u]||v==son[u])continue;        init_que(v,v);    }    // printf("%d top num %d %d\n",u,top[u],num[u]);}void push_up(int root){    maxx[root]=max(maxx[root<<1],maxx[root<<1|1]);    minn[root]=min(minn[root<<1],minn[root<<1|1]);}void push_down(int root){    if(col[root])    {        maxx[root<<1|1]=-maxx[root<<1|1];        minn[root<<1|1]=-minn[root<<1|1];        swap(maxx[root<<1|1],minn[root<<1|1]);        maxx[root<<1]=-maxx[root<<1];        minn[root<<1]=-minn[root<<1];        swap(maxx[root<<1],minn[root<<1]);        col[root<<1]^=1;        col[root<<1|1]^=1;        col[root]=0;    }}void update(int root,int l,int r,int loc,int z){    if(l>loc||r<loc)return;    if(l==r)    {        col[root]=0;        maxx[root]=z;        minn[root]=z;        return;    }    push_down(root);    int mid=(l+r)>>1;    update(root<<1,l,mid,loc,z);    update(root<<1|1,mid+1,r,loc,z);    push_up(root);}void update1(int root, int l,int r,int x,int y){    if(l>y||r<x)return;    if(x<=l&&r<=y)    {        maxx[root]=-maxx[root];        minn[root]=-minn[root];        swap(maxx[root],minn[root]);        col[root]^=1;        return;    }    push_down(root);    int mid=(l+r)>>1;    update1(root<<1,l,mid,x,y);    update1(root<<1|1,mid+1,r,x,y);    push_up(root);}int query(int root ,int l,int r,int x,int y){    if(l>y||r<x)return -0x3f3f3f3f;    if(x<=l&&r<=y)    {        return maxx[root];    }    push_down(root);    int mid=(l+r)>>1;    return max(query(root<<1,l,mid,x,y),query(root<<1|1,mid+1,r,x,y));}int main(){    ///freopen("data.txt","r",stdin);    int T;    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);            d[i][0]=u,d[i][1]=v,d[i][2]=w;            addedge(u,v,w);            addedge(v,u,w);        }        int root=(n+1)>>1;        z=0,siz[0]=0,dep[0]=0;        dfs(root,0);        init_que(root,root);        for(int i=1; i<n; i++)        {            if(dep[d[i][0]]>dep[d[i][1]])            {                swap(d[i][0],d[i][1]);            }            update(1,1,z,num[d[i][1]],d[i][2]);        }        while(1)        {            char s[10];            scanf("%s",s);            if(s[0]=='D')break;            int x,y;            scanf("%d%d",&x,&y);            if(s[0]=='C')            {                update(1,1,z,num[d[x][1]],y);            }            else if(s[0]=='N')            {                int f1=top[x],f2=top[y];                while(f1!=f2)                {                    if(dep[f1]<dep[f2])                    {                        swap(f1,f2);                        swap(x,y);                    }                    if(x!=y)                    {                        update1(1,1,z,num[f1],num[x]);                        x=fa[f1],f1=top[x];                    }                }                if(x!=y)                {                    if(dep[x]>dep[y])                    {                        swap(x,y);                    }                    update1(1,1,z,num[son[x]],num[y]);                }            }            else            {                int f1=top[x],f2=top[y];                int sum=-0x3f3f3f3f;                while(f1!=f2)                {                    if(dep[f1]<dep[f2])                    {                        swap(f1,f2);                        swap(x,y);                    }                    sum=max(sum,query(1,1,z,num[f1],num[x]));                    x=fa[f1],f1=top[x];                }                if(x!=y)                {                    if(dep[x]>dep[y])                    {                        swap(x,y);                    }                    sum=max(query(1,1,z,num[son[x]],num[y]),sum);                }                printf("%d\n",sum);            }        }    }    return 0;}


0 0
原创粉丝点击