您的位置:首页 > 其它

bzoj1036 codevs2460: [ZJOI2008]树的统计 树链剖分

2014-09-10 17:28 267 查看
简单树链抛分,竟然总是dfs写错。。。。。不能忍。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
#define maxn 60000
#define ll long long
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define INF   0x7fffffff
int fa[maxn],siz[maxn],top[maxn],w[maxn],son[maxn],dep[maxn],id;
struct node
{
int v,next;
}g[maxn];
int num,n,first[maxn],val[maxn];
int tree[maxn<<1],sum[maxn<<1];
void build(int a,int b)
{
num++;
g[num].v=b;
g[num].next=first[a];
first[a]=num;
}
void dfs(int now)
{
int v,ceng;
int maxv=0,flag=0;
siz[now]=1;
for(int i=first[now];i;i=g[i].next)
{
v=g[i].v;
if(v==fa[now]) continue;
dep[v]=dep[now]+1;
fa[v]=now;
dfs(v);
siz[now]+=siz[v];
if(siz[v]>maxv)
{
maxv=siz[v];
flag=v;
}
}
son[now]=flag;
}
void getid(int now,int root)
{
w[now]=++id;
top[now]=root;
if(son[now]) getid(son[now],top[now]);
for(int i=first[now]; i; i=g[i].next)
{
if(g[i].v!=son[now]&&g[i].v!=fa[now])
{
getid(g[i].v,g[i].v);
}
}
}
void pushup(int rt)
{
sum[rt]=sum[(rt<<1)]+sum[(rt<<1|1)];
tree[rt]=max(tree[(rt<<1)],tree[(rt<<1|1)]);
}
void update(int rt,int l,int r,int x,int add)
{
if(l==r)
{
tree[rt]=sum[rt]=add;
return;
}
int m=(l+r)>>1;
if(x<=m)
{
update(lson,x,add);
}
if(x>m)
{
update(rson,x,add);
}
pushup(rt);
}
int querymax(int rt,int l,int r,int x,int y)
{
if(l>=x&&y>=r)
{
return tree[rt];
}
int tmp=-INF;
int m=(l+r)>>1;
if(x<=m)
{
tmp=max(tmp,querymax(lson,x,y));
}
if(y>m)
{
tmp=max(tmp,querymax(rson,x,y));
}
return tmp;
}
int querysum(int rt,int l,int r,int x,int y)
{
if(l>=x&&y>=r)
{
return sum[rt];
}
int tmp=0;
int m=(l+r)>>1;
if(x<=m)
{
tmp+=querysum(lson,x,y);
}
if(y>m)
{
tmp+=querysum(rson,x,y);
}
return tmp;
}
int getans(int x,int y,int op)
{
int ans=-INF,asum=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
{
swap(x,y);
}
if(op==1)
{
ans=max(ans,querymax(1,1,n,w[top[x]],w[x]));
}
else
{
asum+=querysum(1,1,n,w[top[x]],w[x]);
}
x=fa[top[x]];
}
if(op==1)
{
if(dep[x]>dep[y]) ans=max(ans,querymax(1,1,n,w[y],w[x]));
else ans=max(ans,querymax(1,1,n,w[x],w[y]));
}
else
{
if(dep[x]>dep[y]) asum+=querysum(1,1,n,w[y],w[x]);
else asum+=querysum(1,1,n,w[x],w[y]);
}
if(op==1) return ans;
else return asum;
}
int main()
{
char str[20];
int a,b,c;
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d%d",&a,&b);
build(a,b);
build(b,a);
}
dfs(1);
//printf("orzn");
getid(1,1);
//printf("orzn");
for(int i=1;i<=n;i++)
{
scanf("%d",&val[i]);
update(1,1,n,w[i],val[i]);
}

scanf("%d",&c);
while(c--)
{
scanf("%s%d%d",str,&a,&b);
if(str[1]=='M')
{
printf("%d\n",getans(a,b,1));
}
else if(str[1]=='S')
{
printf("%d\n",getans(a,b,2));
}
else
{
update(1,1,n,w[a],b);
}
}
return 0;
}

/*
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
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: