bzoj2157: 旅游

lct裸题.

记得很久之前打算学lct的时候看着好难啊.结果是水题.

调了半天去看了眼别人代码,发现取相反数的时候忘了把本身的v取反了.

  1 //Achen
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<queue>
  7 #include<cmath>
  8 const int N=4e4+7;
  9 typedef long long LL;
 10 using namespace std;
 11 int n,q,tot,id[N],v[N],ch[N][2],p[N],is[N],mx[N],mi[N],sum[N],flip[N],lz[N],sz[N];
 12 char o[20];
 13 
 14 template<typename T>void read(T &x) {
 15     char ch=getchar(); T f=1; x=0;
 16     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
 17     if(ch=='-') f=-1,ch=getchar();
 18     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
 19 }
 20 
 21 #define lc ch[x][0]
 22 #define rc ch[x][1]
 23 void update(int x) {
 24     sz[x]=sz[lc]+sz[rc]+1;
 25     sum[x]=sum[lc]+sum[rc]+v[x];
 26     mx[x]=is[x]?-1e9:v[x];
 27     mi[x]=is[x]?1e9:v[x]; 
 28     if(lc) mx[x]=max(mx[x],mx[lc]),mi[x]=min(mi[x],mi[lc]);
 29     if(rc) mx[x]=max(mx[x],mx[rc]),mi[x]=min(mi[x],mi[rc]);
 30 }
 31 
 32 void cg(int x) { lz[x]^=1; v[x]*=-1; swap(mx[x],mi[x]); mi[x]*=-1; mx[x]*=-1; sum[x]*=-1; }
 33 void down(int x) {
 34     if(lz[x]) {
 35         lz[x]^=1;
 36         if(lc) cg(lc);
 37         if(rc) cg(rc);
 38     }
 39     if(flip[x]) {
 40         if(lc) flip[lc]^=1;
 41         if(rc) flip[rc]^=1;
 42         swap(lc,rc);
 43         flip[x]^=1; 
 44     }
 45 }
 46 
 47 int isroot(int x) {return (ch[p[x]][0]!=x&&ch[p[x]][1]!=x);}
 48 
 49 void rotate(int x) {
 50     int y=p[x],z=p[y],l=(x==ch[y][1]),r=l^1;
 51     if(!isroot(y)) ch[z][y==ch[z][1]]=x; p[x]=z;
 52     ch[y][l]=ch[x][r]; p[ch[x][r]]=y;
 53     ch[x][r]=y; p[y]=x;
 54     update(y); update(x);
 55 }
 56 
 57 void splay(int x) {
 58     static int g[N],top=0,tp;
 59     for(tp=x;!isroot(tp);tp=p[tp]) g[++top]=tp;
 60     g[++top]=tp;
 61     while(top) down(g[top--]);
 62     for(;!isroot(x);rotate(x)) {
 63         int y=p[x],z=p[y];
 64         if(!isroot(y)) 
 65             ((x==ch[y][1])^(y==ch[z][1]))?rotate(x):rotate(y);
 66     }
 67 }
 68 
 69 void access(int x) {
 70     for(int t=0;x;x=p[t=x]) {
 71         splay(x);
 72         rc=t;
 73         update(x);
 74     }
 75 }
 76 
 77 void newroot(int x) {
 78     access(x);
 79     splay(x);
 80     flip[x]^=1;
 81 }
 82 
 83 void lik(int x,int y,int z) {
 84     newroot(x);
 85     splay(x);
 86     newroot(y);
 87     splay(y);
 88     p[x]=p[y]=z;
 89 }
 90 
 91 int main() {
 92 #ifdef orzllj
 93     freopen("1.in","r",stdin);
 94 #endif
 95     read(n);
 96     for(int i=1;i<=n;i++) {
 97         v[++tot]=0;
 98         mi[tot]=1e9; mx[tot]=-1e9;
 99         is[tot]=1; sz[tot]=1;
100     }
101     for(int i=1;i<n;i++) {
102         int x,y,z,w;
103         read(x); read(y); read(w);
104         x++; y++;
105         z=++tot; v[z]=w; sz[z]=1;
106         lik(x,y,z); id[i]=tot;
107     }
108     read(q);
109     while(q--) {
110         scanf("%s",o);
111         if(o[0]=='C') {
112             int i,w;
113             read(i); read(w);
114             splay(id[i]);
115             v[id[i]]=w; 
116             update(id[i]);;
117         }
118         else {
119             int x,y;
120             read(x); read(y);
121             x++; y++;
122             newroot(x);
123             access(y);
124             splay(y);
125             if(o[0]=='N') cg(y);
126             else if(o[0]=='S') printf("%d\n",sum[y]);
127             else if(o[1]=='A') printf("%d\n",mx[y]);
128             else if(o[1]=='I') printf("%d\n",mi[y]);
129         }
130     }
131     return 0;
132 }
133 /*
134 3
135 0 1 1
136 1 2 2
137 8
138 SUM 0 2
139 MAX 0 2
140 N 0 1
141 SUM 0 2
142 MIN 0 2
143 C 1 3
144 SUM 0 2
145 MAX 0 2
146 */
View Code

 

posted @ 2017-12-21 19:28  啊宸  阅读(124)  评论(0编辑  收藏  举报