bzoj 1036 [ZJOI2008] 树的统计 树链剖分模板题

来源:互联网 发布:知乎周刊在哪里看 编辑:程序博客网 时间:2024/06/10 16:57

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.csdn.net/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:16int 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]));        }    }}
原创粉丝点击