树链剖分模板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;
}
#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;
}
相关文章推荐
- C#中this的用法,你用过几种?
- 输入一个年份,判断是否是闰年
- Java 语言基础
- java环境配置
- 强制删除sqlserver2008发布
- NullPointerException android.support.v4.app.FragmentManagerImpl.saveFragmentBasicState
- 238 Product of Array Except Self
- poj 3280 区间dp
- C#字典的遍历方法
- 解决SQL server2005数据库死锁的经验心得
- Zend Studio 上 安装使用Aptana插件
- 初试FitNesse
- 2025 查找最大元素
- HDU 4979 A simple math problem.
- java 堆和栈
- C#索引器的使用
- 使用URLDecoder和URLEncoder对中文进行处理
- bestcoder48 第二题
- 2894 Txx考试
- POJ2964日历问题