您的位置:首页 > 其它

树链剖分模板bzoj1036

2015-07-20 15:38 369 查看
#include <iostream>

#include<stdio.h>

#include<string.h>

#include<string>

#include<algorithm>

using namespace std;

const int maxn=30000+10;

int head[maxn];

int next[2*maxn];

int to[2*maxn];

int tot;

int idx;

void init()

{

tot=0;

idx=0;

memset(head,-1,sizeof(head));

}

void addedge(int u,int v)

{

to[tot]=v;

next[tot]=head[u];

head[u]=tot++;

}

int fa[maxn];

int son[maxn];

int siz[maxn];

int dep[maxn];

int top[maxn];

int id[maxn];

int val[maxn];

void dfs1(int u,int f,int d)

{

dep[u]=d;

fa[u]=f;

siz[u]=1;

son[u]=0;

for(int i=head[u];i!=-1;i=next[i])

{

int v=to[i];

if(v==f)

continue;

//cout<<"v: "<<v<<endl;

dfs1(v,u,d+1);

siz[u]+=siz[v];

if(siz[son[u]]<siz[v])

son[u]=v;

}

}

void dfs2(int u,int tp)

{

//cout<<"u: "<<u<<endl;

id[u]=++idx;

top[u]=tp;

if(son[u]>0)

dfs2(son[u],tp);

for(int i=head[u];i!=-1;i=next[i])

{

int v=to[i];

if(v==son[u]||v==fa[u])

continue;

dfs2(v,v);

}

}

const int inf=0x3f3f3f3f;

struct tree

{

int l;

int r;

int maxx;

int sum;

}node[4*maxn];

void build(int l,int r,int x=0)

{

node[x].l=l;

node[x].r=r;

if(l==r)

{

node[x].sum=val[l];

node[x].maxx=val[l];

return ;

}

int mid=(l+r)/2;

build(l,mid,2*x+1);

build(mid+1,r,2*x+2);

node[x].maxx=max(node[x*2+1].maxx,node[2*x+2].maxx);

node[x].sum=node[2*x+1].sum+node[2*x+2].sum;

}

void change(int l,int b,int x=0)

{

if(node[x].l==node[x].r)

{

node[x].sum=b;

node[x].maxx=b;

return ;

}

int mid=(node[x].l+node[x].r)/2;

if(l<=mid)

change(l,b,2*x+1);

else

change(l,b,2*x+2);

node[x].maxx=max(node[2*x+1].maxx,node[2*x+2].maxx);

node[x].sum=node[2*x+1].sum+node[2*x+2].sum;

}

int querry(int l,int r,int ty,int x=0)

{

// cout<<"x: "<<x<<"L:"<<node[x].l<<" r: "<<node[x].r<<endl;

if(l<=node[x].l&&r>=node[x].r)

{

if(ty>0)

return node[x].sum;

else

return node[x].maxx;

}

int mid=(node[x].l+node[x].r)/2;

int ans=-inf,tmp;

if(ty>0)

ans=0;

if(l<=mid)

{

tmp=querry(l,r,ty,2*x+1);

if(ty>0)

ans+=tmp;

else

ans=max(ans,tmp);

}

if(r>mid)

{

tmp=querry(l,r,ty,2*x+2);

if(ty>0)

ans+=tmp;

else

ans=max(ans,tmp);

}

return ans;

}

int gao(int u,int v,int ty)

{

int ans=-inf;

// cout<<"sb"<<endl;

if(ty>0)

ans=0;

int tmp;

int id1=top[u];

int id2=top[v];

// cout<<"id1:"<<id1<<" id2:"<<id2<<endl;

while(id1!=id2)

{

if(dep[id1]<dep[id2])

{

swap(id1,id2);

swap(u,v);

}

tmp=querry(id[id1],id[u],ty);

if(ty>0)

ans+=tmp;

else

ans=max(ans,tmp);

u=fa[id1];

id1=top[u];

}

if(dep[u]>dep[v])

swap(u,v);

tmp=querry(id[u],id[v],ty);

if(ty>0)

ans+=tmp;

else

ans=max(ans,tmp);

return ans;

}

int main()

{

int n;

while(scanf("%d",&n)!=EOF)

{

init();

for(int i=1;i<n;i++)

{

int a,b;

scanf("%d%d",&a,&b);

addedge(a,b);

addedge(b,a);

}

dfs1(1,0,1);

dfs2(1,1);

for(int i=1;i<=n;i++)

{

scanf("%d",&val[id[i]]);

}

build(1,idx);

int q;

char que[10];

scanf("%d",&q);

for(int i=1;i<=q;i++)

{

int a,b;

scanf("%s%d%d",que,&a,&b);

if(que[0]=='C')

{

change(id[a],b);

}

else

{

int ty=0;

if(que[1]=='S')

ty=1;

printf("%d\n",gao(a,b,ty));

}

}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: