bzoj 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5442 Solved: 2285
[Submit][Status]
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
这道题主要是试验了一下用bfs写链剖,以前居然不知道将bfs的队列改为栈就可以搞出dfs序。。。。。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<string> #include<queue> using namespace std; #ifdef WIN32 #define LL "%I64d" #else #define LL "%lld" #endif #define MAXN 31000 #define MAXT 121000 #define MAXV MAXN*2 #define MAXE MAXV*2 #define INF 0x3f3f3f3f #define INFL 0x3f3f3f3f3f3f3f3fLL #define lch (now<<1) #define rch (now<<1^1) typedef long long qword; inline int nextInt() { char ch; int x=0; bool flag=false; do ch=(char)getchar(),flag=(ch=='-')?true:flag; while(ch<'0'||ch>'9'); do x=x*10+ch-'0'; while (ch=(char)getchar(),ch<='9' && ch>='0'); return x*(flag?-1:1); } struct sgt_t { int l,r; qword mx,sum; }sgt[MAXT]; int val[MAXT]; void Build_tree(int now,int l,int r) { sgt[now].l=l; sgt[now].r=r; if (l==r) { sgt[now].mx=sgt[now].sum=val[l]; return ; } Build_tree(lch,l,(l+r)>>1); Build_tree(rch,((l+r)>>1)+1,r); sgt[now].mx=max(sgt[lch].mx,sgt[rch].mx); sgt[now].sum=sgt[lch].sum+sgt[rch].sum; } void Chg_val(int now,int pos) { if (sgt[now].l == sgt[now].r) { sgt[now].mx=sgt[now].sum=val[pos]; return ; } if (pos<=(sgt[now].l+sgt[now].r>>1)) Chg_val(lch,pos); else Chg_val(rch,pos); sgt[now].mx=max(sgt[lch].mx,sgt[rch].mx); sgt[now].sum=sgt[lch].sum+sgt[rch].sum; } qword Qry_sum(int now,int l,int r) { if (sgt[now].l == l && sgt[now].r == r) { return sgt[now].sum; } int mid=(sgt[now].l+sgt[now].r)>>1; if (r<=mid) return Qry_sum(lch,l,r); if (mid<l) return Qry_sum(rch,l,r); return Qry_sum(lch,l,mid)+Qry_sum(rch,mid+1,r); } qword Qry_max(int now,int l,int r) { if (sgt[now].l == l && sgt[now].r == r) { return sgt[now].mx; } int mid=(sgt[now].l+sgt[now].r)>>1; if (r<=mid) return Qry_max(lch,l,r); if (mid<l) return Qry_max(rch,l,r); return max(Qry_max(lch,l,mid),Qry_max(rch,mid+1,r)); } int n,m; struct Edge { int np; Edge *next; }E[MAXE],*V[MAXV]; int tope=-1; void addedge(int x,int y) { E[++tope].np=y; E[tope].next=V[x]; V[x]=&E[tope]; } int stack[MAXN]; int tops=-1; int seq[MAXN]; int pos[MAXN]; int fa[MAXN]; int siz[MAXN],son[MAXN],depth[MAXN]; int top[MAXN]; void bfs(int x) { int now; int bst; int i; int idx; Edge *ne; stack[0]=x; tops=0; idx=-1; while (~tops) { now=stack[tops--]; seq[++idx]=now; for (ne=V[now];ne;ne=ne->next) { if (ne->np==fa[now])continue; depth[ne->np]=depth[now]+1; fa[ne->np]=now; stack[++tops]=ne->np; } } for (i=n-1;i>=0;i--) { now=seq[i]; siz[now]=1; bst=0; son[now]=-1; for (ne=V[now];ne;ne=ne->next) { if (ne->np==fa[now])continue; siz[now]+=siz[ne->np]; if (siz[ne->np]>bst) { son[now]=ne->np; bst=siz[ne->np]; } } } stack[0]=x; top[x]=x; tops=0; idx=0; while (~tops) { now=stack[tops--]; seq[++idx]=now; for (ne=V[now];ne;ne=ne->next) { if (ne->np==fa[now] || ne->np==son[now])continue; top[ne->np]=ne->np; stack[++tops]=ne->np; } if (~son[now]) { stack[++tops]=son[now]; top[son[now]]=top[now]; } } for (i=1;i<=n;i++) { pos[seq[i]]=i; } } int main() { //freopen("input.txt","r",stdin); //freopen("output.txt","w",stdout); int i,j,k; int x,y,z; scanf("%d",&n); for (i=1;i<n;i++) { scanf("%d%d",&x,&y); addedge(x,y); addedge(y,x); } bfs(1); for (i=1;i<=n;i++) { scanf("%d",&x); val[pos[i]]=x; } Build_tree(1,1,n); char opt[10]; qword ans=0; scanf("%d\n",&m); for (i=0;i<m;i++) { scanf("%s %d %d\n",opt,&x,&y); if (opt[1]=='M') { ans=-INF; while (true) { if (top[x]==top[y]) { if (depth[x]>depth[y])swap(x,y); ans=max(ans,Qry_max(1,pos[x],pos[y])); y=x; break; } if (depth[top[x]]<depth[top[y]])swap(x,y); ans=max(ans,Qry_max(1,pos[top[x]],pos[x])); x=fa[top[x]]; } printf(LL"\n",ans); }else if (opt[1]=='S') { ans=0; while (true) { if (top[x]==top[y]) { if (depth[x]>depth[y])swap(x,y); ans+=Qry_sum(1,pos[x],pos[y]); break; } if (depth[top[x]]<depth[top[y]])swap(x,y); ans+=Qry_sum(1,pos[top[x]],pos[x]); x=fa[top[x]]; } printf(LL "\n",ans); }else { val[pos[x]]=y; Chg_val(1,pos[x]); } } return 0; }
by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载
本博客已停用,新博客地址:http://mhy12345.xyz