POJ-3237:Tree(树链剖分)

来源:互联网 发布:单片机与上位机通信 编辑:程序博客网 时间:2024/06/04 17:49

Tree
Time Limit: 5000MS Memory Limit: 131072KTotal Submissions: 10785 Accepted: 2800

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

思路:树链剖分。

#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<iostream>using namespace std;const int MAX=2e5;struct edg{int x,y,z;}edg[MAX];vector<int>e[MAX];struct lenka{    int l,r;    int ma;}A[MAX<<2];int d[MAX],son[MAX],fa[MAX],siz[MAX],top[MAX],val[MAX],num[MAX],all;void build(int k,int l,int r){    A[k].l=l,A[k].r=r;    if(l==r){A[k].ma=val[l];return;}    build(2*k,l,(l+r)/2);    build(2*k+1,(l+r)/2+1,r);    A[k].ma=max(A[2*k].ma,A[2*k+1].ma);}void negat(int k,int x,int y){    if(A[k].l==A[k].r){A[k].ma*=-1;return;}    if(y<=A[2*k].r)negat(2*k,x,y);    else if(x>=A[2*k+1].l)negat(2*k+1,x,y);    else    {        negat(2*k,x,A[2*k].r);        negat(2*k+1,A[2*k+1].l,y);    }    A[k].ma=max(A[2*k].ma,A[2*k+1].ma);}void change(int k,int x,int y){    if(x==A[k].l&&x==A[k].r){A[k].ma=y;return;}    if(x<=A[2*k].r)change(2*k,x,y);    else change(2*k+1,x,y);    A[k].ma=max(A[2*k].ma,A[2*k+1].ma);}int ask(int k,int x,int y){    if(x==A[k].l&&y==A[k].r)return A[k].ma;    if(y<=A[2*k].r)return ask(2*k,x,y);    else if(x>=A[2*k+1].l)return ask(2*k+1,x,y);    return max(ask(2*k,x,A[2*k].r),ask(2*k+1,A[2*k+1].l,y));}void dfs1(int k,int f,int dep){    d[k]=dep;    siz[k]=1;    son[k]=0;    fa[k]=f;    for(int i=0;i<e[k].size();i++)    {        int nex=e[k][i];        if(nex==f)continue;        dfs1(nex,k,dep+1);        siz[k]+=siz[nex];        if(siz[son[k]]<siz[nex])son[k]=nex;    }}void dfs2(int k,int tp){    top[k]=tp;    num[k]=++all;    if(son[k])dfs2(son[k],tp);    for(int i=0;i<e[k].size();i++)    {        if(e[k][i]==fa[k]||e[k][i]==son[k])continue;        dfs2(e[k][i],e[k][i]);    }}int QWQ(int x,int y){    int tpx=top[x],tpy=top[y],ans=-(1<<30);//数据范围不知道,一开始设的为0,一直WA    while(tpx!=tpy)    {        if(d[tpx]<d[tpy])        {            swap(tpx,tpy);            swap(x,y);        }        ans=max(ans,ask(1,num[tpx],num[x]));        x=fa[tpx];        tpx=top[x];    }    if(x==y)return ans;    if(d[x]>d[y])swap(x,y);    return max(ans,ask(1,num[son[x]],num[y]));}void QAQ(int x,int y){    int tpx=top[x],tpy=top[y];    while(tpx!=tpy)    {        if(d[tpx]<d[tpy])        {            swap(tpx,tpy);            swap(x,y);        }        negat(1,num[tpx],num[x]);        x=fa[tpx];        tpx=top[x];    }    if(x==y)return;    if(d[x]>d[y])swap(x,y);    negat(1,num[son[x]],num[y]);}int main(){    int T,n;cin>>T;    while(T--)    {        scanf("%d",&n);        for(int i=1;i<=n;i++)e[i].clear();        memset(siz,0,sizeof siz);        memset(d,0,sizeof d);        memset(son,0,sizeof son);        for(int i=1;i<n;i++)        {            scanf("%d%d%d",&edg[i].x,&edg[i].y,&edg[i].z);            e[edg[i].x].push_back(edg[i].y);            e[edg[i].y].push_back(edg[i].x);        }        all=0;        dfs1(1,0,1);        dfs2(1,1);        for(int i=1;i<n;i++)        {            if(d[edg[i].x]<d[edg[i].y])swap(edg[i].x,edg[i].y);            val[num[edg[i].x]]=edg[i].z;        }        build(1,1,all);        char op[20];        while(scanf("%s",op)!=EOF&&strcmp(op,"DONE")!=0)        {            int x,y;            scanf("%d%d",&x,&y);            if(strcmp(op,"QUERY")==0)printf("%d\n",QWQ(x,y));            else if(strcmp(op,"CHANGE")==0)change(1,num[edg[x].x],y);            else QAQ(x,y);        }    }    return 0;}





原创粉丝点击