Submit: 1488 Solved: 670
Description
Ray 乐忠于旅游,这次他来到了T 城。T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接。为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有一条路径。换句话说, T 城中只有N − 1 座桥。Ray 发现,有些桥上可以看到美丽的景色,让人心情愉悦,但有些桥狭窄泥泞,令人烦躁。于是,他给每座桥定义一个愉悦度w,也就是说,Ray 经过这座桥会增加w 的愉悦度,这或许是正的也可能是负的。有时,Ray 看待同一座桥的心情也会发生改变。现在,Ray 想让你帮他计算从u 景点到v 景点能获得的总愉悦度。有时,他还想知道某段路上最美丽的桥所提供的最大愉悦度,或是某段路上最糟糕的一座桥提供的最低愉悦度。
Input
输入的第一行包含一个整数N,表示T 城中的景点个数。景点编号为 0...N − 1。接下来N − 1 行,每行三个整数u、v 和w,表示有一条u 到v,使 Ray 愉悦度增加w 的桥。桥的编号为1...N − 1。|w| <= 1000。输入的第N + 1 行包含一个整数M,表示Ray 的操作数目。接下来有M 行,每行描述了一个操作,操作有如下五种形式: C i w,表示Ray 对于经过第i 座桥的愉悦度变成了w。 N u v,表示Ray 对于经过景点u 到v 的路径上的每一座桥的愉悦度都变成原来的相反数。 SUM u v,表示询问从景点u 到v 所获得的总愉悦度。 MAX u v,表示询问从景点u 到v 的路径上的所有桥中某一座桥所提供的最大愉悦度。 MIN u v,表示询问从景点u 到v 的路径上的所有桥中某一座桥所提供的最小愉悦度。测试数据保证,任意时刻,Ray 对于经过每一座桥的愉悦度的绝对值小于等于1000。
Output
对于每一个询问(操作S、MAX 和MIN),输出答案。
Sample Input
0 1 1
1 2 2
8
SUM 0 2
MAX 0 2
N 0 1
SUM 0 2
MIN 0 2
C 1 3
SUM 0 2
MAX 0 2
Sample Output
2
1
-1
5
3
HINT
一共有10 个数据,对于第i (1 <= i <= 10) 个数据, N = M = i * 2000。
Source
树 LCT 模拟
喜闻乐见一上午调一道题
LCT转来转去没法维护边权(不换根的话可以),就把每个边当成一个点,存好权值,连到它的两个端点上。
剩下的就是裸题
那么为什么要调一上午呢?
树上原本的点是不存权值的,所以它们保存的min和max默认是0,所以……
↑傻傻意识不到
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 using namespace std; 9 const int INF=0x3f3f3f3f; 10 const int mxn=400010; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 14 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 15 return x*f; 16 } 17 inline int min(const int x,const int y){return x<y?x:y;} 18 inline int max(const int x,const int y){return x>y?x:y;} 19 struct node{ 20 int ch[2],fa; 21 int val,smm,mi,mx; 22 bool rev,VR; 23 }t[mxn]; 24 inline bool isroot(int &x){ 25 return (t[t[x].fa].ch[0]!=x && t[t[x].fa].ch[1]!=x); 26 } 27 inline void Vrev(int x){ 28 // if(x && t[x].VR){ 29 if(x){ 30 // printf("Vrev:%d\n",x); 31 // int lc=t[x].ch[0],rc=t[x].ch[1]; 32 // t[lc].VR^=1;t[rc].VR^=1; 33 t[x].smm=-t[x].smm; 34 t[x].val=-t[x].val; 35 int r1=t[x].mi,r2=t[x].mx; 36 t[x].mi=-r2;t[x].mx=-r1; 37 t[x].VR^=1; 38 } 39 return; 40 } 41 int ed; 42 void pushup(int x){ 43 int lc=t[x].ch[0],rc=t[x].ch[1]; 44 t[x].mi=min(t[lc].mi,t[rc].mi); 45 t[x].mx=max(t[lc].mx,t[rc].mx); 46 if(x>ed) t[x].mi=min(t[x].mi,t[x].val); 47 if(x>ed) t[x].mx=max(t[x].mx,t[x].val); 48 t[x].smm=t[lc].smm+t[rc].smm+t[x].val; 49 return; 50 } 51 inline void PD(int x){ 52 int lc=t[x].ch[0],rc=t[x].ch[1]; 53 if(t[x].VR){ 54 t[x].VR^=1; 55 if(lc)Vrev(lc); 56 if(rc)Vrev(rc); 57 } 58 if(t[x].rev){ 59 t[lc].rev^=1; 60 t[rc].rev^=1; 61 swap(t[x].ch[0],t[x].ch[1]); 62 t[x].rev^=1; 63 } 64 return; 65 } 66 void rotate(int x){ 67 int y=t[x].fa,z=t[y].fa,lc,rc; 68 if(t[y].ch[0]==x)lc=0;else lc=1;rc=lc^1; 69 if(!isroot(y)){t[z].ch[t[z].ch[1]==y]=x;} 70 t[x].fa=z;t[y].fa=x; 71 t[t[x].ch[rc]].fa=y;t[y].ch[lc]=t[x].ch[rc]; 72 t[x].ch[rc]=y; 73 pushup(y); 74 return; 75 } 76 int st[mxn],top=0; 77 void Splay(int x){ 78 st[top=1]=x; 79 for(int i=x;!isroot(i);i=t[i].fa)st[++top]=t[i].fa; 80 // for(int i=x;t[i].fa;i=t[i].fa)st[++top]=t[i].fa; 81 while(top)PD(st[top--]); 82 while(!isroot(x)){ 83 int y=t[x].fa,z=t[y].fa; 84 if(!isroot(y)){ 85 if((t[y].ch[0]==x)^(t[z].ch[0]==y))rotate(x); 86 rotate(y); 87 } 88 rotate(x); 89 } 90 pushup(x); 91 return; 92 } 93 void access(int x){ 94 for(int y=0;x;x=t[x].fa){ 95 Splay(x); 96 t[x].ch[1]=y; 97 pushup(x); 98 y=x; 99 } 100 return; 101 } 102 void mkroot(int x){ 103 access(x);Splay(x); 104 t[x].rev^=1; 105 return; 106 } 107 void link(int x,int y){mkroot(x);t[x].fa=y;return;} 108 void sov(int x,int y){ 109 mkroot(x); 110 access(y); 111 Splay(y); 112 return; 113 } 114 int n; 115 int id[mxn]; 116 int main(){ 117 int i,j; 118 int u,v,w;char op[5]; 119 n=read(); 120 for(i=1;i<=n;i++){t[i].mi=INF;t[i].mx=-INF;} 121 t[0].mi=INF;t[0].mx=-INF;t[0].smm=t[0].val=0;//init 122 ed=n; 123 for(i=1;i<ed;i++){ 124 u=read()+1;v=read()+1;w=read(); 125 id[i]=++n; 126 t[n].mi=t[n].mx=t[n].smm=t[n].val=w; 127 link(u,n);link(v,n); 128 } 129 int m=read(); 130 while(m--){ 131 scanf("%s",op); 132 switch(op[0]){ 133 case 'C':{ 134 u=read();w=read(); 135 u=id[u]; 136 access(u);Splay(u); 137 t[u].val=w; 138 pushup(u); 139 break; 140 } 141 case 'S':{ 142 u=read()+1;v=read()+1; 143 sov(u,v); 144 printf("%d\n",t[v].smm); 145 break; 146 } 147 case 'M':{ 148 u=read()+1;v=read()+1; 149 sov(u,v); 150 if(op[1]=='A'){ 151 printf("%d\n",t[v].mx); 152 } 153 else{ 154 printf("%d\n",t[v].mi); 155 } 156 break; 157 } 158 case 'N':{ 159 u=read()+1;v=read()+1; 160 sov(u,v); 161 Vrev(v); 162 break; 163 } 164 /* case 'D':{ 165 for(int i=1;i<=n;i++){ 166 printf("#%d: val:%d smm:%d fa:%d lc:%d rc:%d\n",i,t[i].val,t[i].smm,t[i].fa,t[i].ch[0],t[i].ch[1]); 167 } 168 break; 169 }*/ 170 } 171 } 172 return 0; 173 } 174 /* 175 6 176 0 1 3 177 1 2 7 178 2 3 11 179 3 4 24 180 4 5 53 181 20 182 N 1 2 183 SUM 0 5 184 */