1583. [POJ3237]树的维护

★★★☆   输入文件:maintaintree.in   输出文件:maintaintree.out   简单对比
时间限制:5 s   内存限制:128 MB

【题目描述】

给你由N个结点组成的树。树的节点被编号为1到N,边被编号为1到N-1。每一条边有一个权值。然后你要在树上执行一系列指令。指令可以是如下三种之一:

CHANGE i v:将第i条边的权值改成v。

NEGATE a b:将点a到点b路径上所有边的权值变成其相反数。

QUERY a b:找出点a到点b路径上各边的最大权值。

【输入格式】

输入文件的第一行有一个整数N(N<=10000)。

接下来N-1行每行有三个整数a,b,c,代表点a和点b之间有一条权值为c的边。这些边按照其编号从小到大给出。

接下来是若干条指令(不超过10^5条),都按照上面所说的格式。

输入文件的最后一行是"DONE".

【输出格式】

对每个“QUERY”指令,输出一行,即路径上各边的最大权值。

【样例输入】

3

1 2 1

2 3 2

QUERY 1 2

CHANGE 1 3

QUERY 1 2

DONE

【样例输出】

1

3

【提示】

这里的输入输出格式和POJ上原题略有不同。

【来源】

POJ 3237 Tree

题解:

LCT维护一下最大值和最小值,当要变为相反数时,把 最大值变为原来的最小值的相反数,最小值变为原来最大值的相反数 即可。。。

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define INF 1e9
  4 #define MAXN 10010
  5 struct node
  6 {
  7     int left,right,mx,mn,val;
  8 }tree[2*MAXN];
  9 int rev[2*MAXN],tag[2*MAXN],father[2*MAXN],Stack[2*MAXN],n;
 10 int read()
 11 {
 12     int s=0,fh=1;char ch=getchar();
 13     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
 14     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
 15     return s*fh;
 16 }
 17 int isroot(int x)
 18 {
 19     return tree[father[x]].left!=x&&tree[father[x]].right!=x;
 20 }
 21 void pushdown(int x)
 22 {
 23     int l=tree[x].left,r=tree[x].right;
 24     if(rev[x]!=0)
 25     {
 26         rev[x]^=1;rev[l]^=1;rev[r]^=1;
 27         swap(tree[x].left,tree[x].right);
 28     }
 29     if(tag[x]!=0)
 30     {
 31         tag[x]^=1;tag[l]^=1;tag[r]^=1;
 32         tree[l].val=-tree[l].val;
 33         tree[r].val=-tree[r].val;
 34         swap(tree[l].mx,tree[l].mn);
 35         tree[l].mx=-tree[l].mx;tree[l].mn=-tree[l].mn;
 36         swap(tree[r].mx,tree[r].mn);
 37         tree[r].mx=-tree[r].mx;tree[r].mn=-tree[r].mn;
 38     }
 39 }
 40 void pushup(int x)
 41 {
 42     int l=tree[x].left,r=tree[x].right;
 43     tree[x].mx=max(tree[l].mx,tree[r].mx);
 44     if(x>n)tree[x].mx=max(tree[x].mx,tree[x].val);
 45     tree[x].mn=min(tree[l].mn,tree[r].mn);
 46     if(x>n)tree[x].mn=min(tree[x].mn,tree[x].val);
 47 }
 48 void rotate(int x)
 49 {
 50     int y=father[x],z=father[y];
 51     if(!isroot(y))
 52     {
 53         if(tree[z].left==y)tree[z].left=x;
 54         else tree[z].right=x;
 55     }
 56     if(tree[y].left==x)
 57     {
 58         father[x]=z;father[y]=x;tree[y].left=tree[x].right;tree[x].right=y;father[tree[y].left]=y;
 59     }
 60     else
 61     {
 62         father[x]=z;father[y]=x;tree[y].right=tree[x].left;tree[x].left=y;father[tree[y].right]=y;
 63     }
 64     pushup(y);pushup(x);
 65 }
 66 void splay(int x)
 67 {
 68     int top=0,i,y,z;Stack[++top]=x;
 69     for(i=x;!isroot(i);i=father[i])Stack[++top]=father[i];
 70     for(i=top;i>=1;i--)pushdown(Stack[i]);
 71     while(!isroot(x))
 72     {
 73         y=father[x],z=father[y];
 74         if(!isroot(y))
 75         {
 76             if((tree[y].left==x)^(tree[z].left==y))rotate(x);
 77             else rotate(y);
 78         }
 79         rotate(x);
 80     }
 81 }
 82 void access(int x)
 83 {
 84     int last=0;
 85     while(x!=0)
 86     {
 87         splay(x);
 88         tree[x].right=last;pushup(x);
 89         last=x;x=father[x];
 90     }
 91 }
 92 void makeroot(int x)
 93 {
 94     access(x);splay(x);rev[x]^=1;
 95 }
 96 void link(int u,int v)
 97 {
 98     makeroot(u);father[u]=v;splay(u);
 99 }
100 void cut(int u,int v)
101 {
102     makeroot(u);access(v);splay(v);father[u]=tree[v].left=0;
103 }
104 int findroot(int x)
105 {
106     access(x);splay(x);
107     while(tree[x].left!=0)x=tree[x].left;
108     return x;
109 }
110 int main()
111 {
112     freopen("maintaintree.in","r",stdin);
113     freopen("maintaintree.out","w",stdout);
114     int i,a,b,c;
115     char fh[8];
116     n=read();
117     for(i=0;i<=2*n;i++)tree[i].mx=-INF,tree[i].mn=INF;
118     for(i=1;i<n;i++)
119     {
120         a=read();b=read();c=read();
121         tree[n+i].mx=tree[n+i].mn=tree[n+i].val=c;
122         link(a,n+i);link(n+i,b);
123     }
124     while(1)
125     {
126         scanf("\n%s",fh);
127         if(fh[0]=='D')break;
128         if(fh[0]=='Q')
129         {
130             a=read();b=read();
131             makeroot(a);access(b);splay(b);
132             printf("%d\n",tree[b].mx);
133         }
134         else if(fh[0]=='C')
135         {
136             a=read();b=read();
137             makeroot(n+a);tree[n+a].mn=tree[n+a].mx=tree[n+a].val=b;
138         }
139         else
140         {
141             a=read();b=read();
142             makeroot(a);access(b);splay(b);
143             tag[b]^=1;
144             swap(tree[b].mx,tree[b].mn);
145             tree[b].val=-tree[b].val;
146             tree[b].mx=-tree[b].mx;
147             tree[b].mn=-tree[b].mn;
148         }
149     }
150     fclose(stdin);
151     fclose(stdout);
152     return 0;
153 }
View Code

相关文章: