BZOJ 1036 [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 8095 Solved: 3300
[Submit][Status][Discuss]
Description
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身
Input
输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。
Output
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。
Sample Input
4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
1 2
2 3
4 1
4 2 1 3
12
QMAX 3 4
QMAX 3 3
QMAX 3 2
QMAX 2 3
QSUM 3 4
QSUM 2 1
CHANGE 1 5
QMAX 3 4
CHANGE 3 6
QMAX 3 4
QMAX 2 4
QSUM 3 4
Sample Output
4
1
2
2
10
6
5
6
5
16
1
2
2
10
6
5
6
5
16
HINT
Source
题解:以我的常数LCT会挂,就不犯懒了吧。。。
我擦。。。树剖还写错了一发。。。手残错。。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar('\n') 9 #define CH for(int d=0;d<2;d++)if(ch[d]) 10 #define lson x->ch[0],L,M 11 #define rson x->ch[1],M+1,R 12 using namespace std; 13 const int maxn=30000+10,maxnode=60000+10,inf=-1u>>1; 14 struct node{ 15 node*ch[2];int mx,sm,siz;node(){mx=-inf;sm=0;} 16 void init(int a){mx=sm=a;return;} 17 void sett(int a){mx=a;sm=siz*a;return;} 18 void update(){sm=0;mx=-inf;CH{sm+=ch[d]->sm;mx=max(mx,ch[d]->mx);}return;} 19 }seg[maxnode],*nodecnt=seg,*root; 20 int A[maxn],n,Q,pos,cv,_mx,_sm,ql,qr; 21 void build(node*&x=root,int L=1,int R=n){ 22 x=nodecnt++;int M=L+R>>1;if(L==R)x->init(A[M]); 23 else build(lson),build(rson),x->update();x->siz=R-L+1;return; 24 } 25 void update(node*&x=root,int L=1,int R=n){ 26 if(L==R){x->sett(cv);return;} 27 int M=L+R>>1;if(pos<=M)update(lson);else update(rson);x->update();return; 28 } 29 void query(node*x=root,int L=1,int R=n){ 30 if(ql<=L&&R<=qr){ 31 _mx=max(_mx,x->mx); 32 _sm+=x->sm; 33 }else{int M=L+R>>1; 34 if(ql<=M)query(lson);if(qr>M)query(rson); 35 }return; 36 } 37 struct ted{int x,y;ted*nxt;}adj[maxn<<1],*fch[maxn],*ms=adj; 38 void add(int x,int y){ 39 *ms=(ted){x,y,fch[x]};fch[x]=ms++;*ms=(ted){y,x,fch[y]};fch[y]=ms++;return; 40 } 41 int top[maxn],p[maxn],sz=0,siz[maxn],son[maxn],fa[maxn],dep[maxn]; 42 void dfs(int x){ 43 siz[x]=1;dep[x]=dep[fa[x]]+1; 44 for(ted*e=fch[x];e;e=e->nxt){ 45 int v=e->y;if(v!=fa[x]){ 46 fa[v]=x;dfs(v);siz[x]+=siz[v]; 47 if(siz[son[x]]<siz[v])son[x]=v; 48 } 49 }return; 50 } 51 void build(int x,int tp){ 52 p[x]=++sz;top[x]=tp; 53 if(son[x])build(son[x],tp); 54 for(ted*e=fch[x];e;e=e->nxt){ 55 int v=e->y;if(v!=fa[x]&&v!=son[x])build(v,v); 56 }return; 57 } 58 void query(int x,int y){ 59 int f1=top[x],f2=top[y]; 60 while(f1!=f2){ 61 if(dep[f1]<dep[f2])swap(f1,f2),swap(x,y); 62 ql=p[f1];qr=p[x];query();x=fa[f1];f1=top[x]; 63 }if(dep[x]>dep[y])swap(x,y);ql=p[x];qr=p[y];query();return; 64 } 65 inline int read(){ 66 int x=0,sig=1;char ch=getchar(); 67 for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=0; 68 for(;isdigit(ch);ch=getchar())x=10*x+ch-'0'; 69 return sig?x:-x; 70 } 71 inline void write(int x){ 72 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 73 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 74 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 75 } 76 void init(){ 77 n=read(); 78 for(int i=1;i<n;i++)add(read(),read()); 79 dfs(1);build(1,1); 80 for(int i=1;i<=n;i++)A[p[i]]=read(); 81 build(); 82 return; 83 } 84 void work(){ 85 Q=read();int x,y;char s[10]; 86 while(Q--){ 87 scanf("%s",s); 88 if(s[0]=='C')pos=p[read()],cv=read(),update(); 89 else{_mx=-inf;_sm=0;query(read(),read()); 90 if(s[1]=='M')write(_mx),ENT;else write(_sm),ENT; 91 } 92 } 93 return; 94 } 95 void print(){ 96 return; 97 } 98 int main(){init();work();print();return 0;}