1036: [ZJOI2008]树的统计Count
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 4465 Solved: 1858
[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
Sample Output
4
1
2
2
10
6
5
6
5
16
又是找不出错误的时候。。。
参考http://blog.youkuaiyun.com/jiangshibiao/article/details/24669751
#include<algorithm>
#include<vector>
#include<cstring>
#include<string>
#include<iomanip>
#include<cstdio>
#include<stack>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<strstream>
using namespace std;
#define sf scanf
#define pf printf
#define mem(a,b) memset(a,b,sizeof(a));
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define MP make_pair
#define mod 998244353
#define ULL unsigned long long
#define LL long long
#define inf 0x3f3f3f3f
#define md ((ll+rr)>>1)
#define ls (i<<1)
#define rs (ls|1)
#define N 5010
#define M 20020
//2017年08月23日08:36:16
int fst[N],nxt[M],to[M],e,val[N],w[N];
int fa[N],dep[N],sz[N],son[N];
int tid[N],top[N];
int sum[N];
bool vis[N];
int label,n;
int mx[N<<2];
void init(){
mem(fst,-1);
e=0;
}
void add(int u,int v){
to[e]=v,nxt[e]=fst[u];fst[u]=e++;
}
void dfs(int u,int p){
fa[u]=p;
sz[u]=1;
for(int i=fst[u];~i;i=nxt[i]){
int v=to[i];
if(v==p)continue;
dep[v]=dep[u]+1;
dfs(v,u);
sz[u]+=sz[v];
if(sz[son[u]]<sz[v]){
son[u]=sz[v];
}
}
}
void dfs2(int u,int t){
vis[u]=1;
top[u]=t;
tid[u]=++label;
w[label]=val[u];
if(son[u])dfs2(son[u],t);
puts("bad");
for(int i=fst[u];~i;i=nxt[i]){
int v=to[i];
puts("bad");
if(!vis[v])dfs2(v,v);
}
}
void cut(){
dep[1]=sz[1]=0;
mem(son,0);
dfs(1,-1);
mem(vis,0);
label=0;
dfs2(1,1);
}
void build(int ll,int rr,int i){
if(ll==rr){
mx[i]=w[ll]; sum[i]=w[ll];
return;
}
build(ll,md,ls),build(md+1,rr,rs);
mx[i]=max(mx[ls],mx[rs]);
sum[i]=sum[ls]+sum[rs];
}
void update(int x,int v,int ll,int rr,int i){
if(ll==rr){
sum[i]=v;
mx[i]=v;return ;
}
if(x<=md)update(x,v,ll,md,ls);
else update(x,v,md+1,rr,rs);
mx[i]=max(mx[ls],mx[rs]);
sum[i]=sum[ls]+sum[rs];
}
int qmax(int l,int r,int ll,int rr,int i){
if(ll==l&&rr==r)return mx[i];
if(r<=md)
return qmax(l,r,ll,md,ls);
if(l>md)
return qmax(l,r,md+1,rr,rs);
return max(qmax(l,md,ll,md,ls),qmax(md+1,r,md+1,rr,rs));
}
int qsum(int l,int r,int ll,int rr,int i){
if(ll==l&&rr==r)return sum[i];
if(r<=md)
return qsum(l,r,ll,md,ls);
if(l>md)
return qsum(l,r,md+1,rr,rs);
return qsum(l,md,ll,md,ls)+qsum(md+1,r,md+1,r,rs);
}
int calmax(int x,int y){
int ret=-inf;
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]])swap(x,y);
ret=max(ret,qmax(tid[top[y]],tid[y],1,n,1));
y=fa[top[y]];
}
if(x!=y){
if(dep[x]>dep[y])swap(x,y);
ret=max(ret,qmax(tid[x]+1,tid[y],1,n,1));
}
return ret;
}
int calsum(int x,int y){
int ret=0;
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]])swap(x,y);
ret+=(qsum(tid[top[y]],tid[y],1,n,1));
y=fa[top[y]];
}
if(x!=y){
if(dep[x]>dep[y])swap(x,y);
ret+=(qsum(tid[top[y]],tid[y],1,n,1));
}
return ret;
}
int main(){
freopen("in.txt","r",stdin);
sf("%d",&n);
init();
for(int i=1;i<=n-1;++i){
int u,v;sf("%d%d",&u,&v);
add(u,v);add(v,u);
}
rep(i,1,n)sf("%d",&val[i]);
cut();
for(int i=1;i<=n;++i){
pf("%d ",mx[i]);
}puts("");
build(1,n,1);
int m;sf("%d",&m);
while(m--){
char s[10];sf("%s",s);
if(s[0]=='C'){
int x,val;sf("%d%d",&x,&val);
update(x,val,1,n,1);
}
else if(s[1]=='S'){
int u,v;sf("%d%d",&u,&v);
pf("%d\n",calsum(tid[u],tid[v]));
}
else if(s[1]=='M'){
int u,v;sf("%d%d",&u,&v);
pf("%d\n",calmax(tid[u],tid[v]));
}
}
}