bzoj1036: [ZJOI2008]树的统计Count 树链剖分模板

无脑码代码....

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch<='9'&&ch>='0')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
void put(int x){
if(x==0){
putchar('0');
putchar('\n');
return;
}
if(x<0){
putchar('-');
x=-x;
}
int num=0;char ch[16];
while(x) ch[++num]=x%10+'0',x/=10;
while(num) putchar(ch[num--]);
putchar('\n');
}
struct one
{
    int y,next;
};
one e[60100];
struct ppp
{
    int l,r,val,maxn;
};
ppp tree[130000];
char s[20];
int maxn=1000000000,maxn2=-1000000000,a[30010],w[30010],n,m,fa[30010],d[30010],sizer[30010],top[30010],lin[30010],len=0,din[30010],dout[30010],wson[30010],cnt=0;
 
 
/*void dfs1(int x,int f)  
{  
    int y;  
    fa[x]=f;  
    wson[x]=0;//the heaviest son  
    sizer[x]=1;  
    for (int i=lin[x];i;i=e[i].next)  
        if (e[i].y!=f)  
        {  
            y=e[i].y;  
            d[y]=d[x]+1;  
            dfs1(y,x);  
            sizer[x]+=sizer[y];  
            if (sizer[wson[x]]<sizer[y])  
                wson[x]=y;  
        }  
}  */
void dfs1(int p,int f)
{
    int y;  
    fa[p]=f;  
    wson[p]=0;
    sizer[p]=1;  
    for(int i=lin[p];i;i=e[i].next)
    {
        int maxnx2=0,ww=0;
        if(e[i].y!=f)
        {
            y=e[i].y;
            d[y]=d[p]+1;
            dfs1(y,p);
            sizer[p]+=sizer[y];
            /*if(sizer[y]>maxnx2)
            {
                maxnx2=sizer[y];
                wson[p]=y;
            }*/
            if (sizer[wson[p]]<sizer[y])  
                wson[p]=y;  
        }
    }
}
void dfs2(int p)
{
    din[p]=++cnt;
    w[cnt]=a[p];
    if(!top[p])top[p]=p;
    if(wson[p])
    {
        top[wson[p]]=top[p];
        dfs2(wson[p]);
    }
    for(int i=lin[p];i;i=e[i].next)
    {
        if(fa[p]==e[i].y||e[i].y==wson[p])continue;
            dfs2(e[i].y);
    }
    //dout[p]=cnt;
}
void insert(int x,int y)
{
    e[++len].next=lin[x];
    lin[x]=len;
    e[len].y=y;
}
void maketree(int l,int r,int id)
{
    tree[id].l=l;tree[id].r=r;
    if(l>=r)
    {
        tree[id].maxn=w[l];
        tree[id].val=w[l];
        return;
    }
    int mid=(l+r)>>1;
    maketree(l,mid,id<<1);
    maketree(mid+1,r,id<<1|1);
    tree[id].maxn=max(tree[id<<1].maxn,tree[id<<1|1].maxn);
    tree[id].val=tree[id<<1].val+tree[id<<1|1].val;
}
/*void chag(int l,int val,int id)
{
    if(l<tree[id].l||l>tree[id].r)return;
    if(tree[id].l==tree[id].r){tree[id].maxn=val;tree[id].val=val;return;}
    int mid=(tree[id].l+tree[id].r)>>1;
    if(l<=mid)chag(l,val,id<<1);
    else chag(l,val,id<<1|1);
    tree[id].maxn=max(tree[id<<1].maxn,tree[id<<1|1].maxn);
    tree[id].val=tree[id<<1].val+tree[id<<1|1].val;
}*/
void updata(int p)  
{  
    tree[p].val=tree[p<<1].val+tree[p<<1|1].val;  
    tree[p].maxn=max(tree[p<<1].maxn,tree[p<<1|1].maxn);  
}  
void chag(int x,int y,int p)  
{  
    if (tree[p].l==x && tree[p].r==x)  
    {  
        tree[p].val=tree[p].maxn=y;  
        return ;  
    }  
    int mid=(tree[p].l+tree[p].r) >> 1;  
    if (x<=mid) chag(x, y,p<<1);  
    if (x>mid) chag(x, y,p<<1|1);  
    updata(p);  
}  
/*int putit2(int l,int r,int id)
{
    if(tree[id].r<l||r<tree[id].l)return -maxn;
    if(tree[id].r<=r&&tree[id].l>=l)return tree[id].maxn;
    int a1=putit2(l,r,id<<1);
    int a2=putit2(l,r,id<<1|1);
    a1=max(a1,a2);
    return a1;
}*/
int putit2(int l,int r,int p)  
{  
    if (tree[p].l==l && tree[p].r==r)  
        return tree[p].maxn;  
    int mid=(tree[p].l+tree[p].r) >> 1;  
    if (r<=mid) return putit2(l, r,p<<1);  
    if (l>mid) return putit2(l, r,p<<1|1);  
    if (l<=mid && r>mid)  
    {  
        int s1=putit2(l, mid,p<<1);  
        int s2=putit2(mid+1, r,p<<1|1);  
        return max(s1,s2);  
    }  
}  
void putit1(int x,int y)
{
    int ans=-maxn;
    while(top[x]!=top[y])
    {
        if(d[top[x]]<d[top[y]])
        {
            ans=max(ans,putit2(din[top[y]],din[y],1));
            y=fa[top[y]];
        }
        else
        {
            ans=max(ans,putit2(din[top[x]],din[x],1));
            x=fa[top[x]];
        }
    }
    if(d[x]<d[y])ans=max(ans,putit2(din[x],din[y],1));
    else ans=max(ans,putit2(din[y],din[x],1));
    put(ans);
}
/*int putsum2(int l,int r,int id)
{
    if(tree[id].r<l||r<tree[id].l)return 0;
    if(tree[id].r<=r&&tree[id].l>=l)return tree[id].val;
    int mid=(tree[id].r+tree[id].l)>>1;
    if(l>=mid)
    int a1=putsum2(l,r,id<<1);
    int a2=putsum2(l,r,id<<1|1);
    return a1+a2;
}*/
int putsum2(int l,int r,int p)  
{  
    if (tree[p].l==l && tree[p].r==r)  
        return tree[p].val;  
    int mid=(tree[p].l+tree[p].r) >> 1;  
    if (r<=mid) return putsum2(l, r,p<<1);  
    if (l>mid) return putsum2( l, r,p<<1|1);  
    if (l<=mid && r>mid)  
    {  
        int s1=putsum2(l, mid,p<<1);  
        int s2=putsum2(mid+1, r,p<<1|1);  
        return s1+s2;  
    }  
}  
void putsum1(int x,int y)
{
    int ans=0;
    while(top[x]!=top[y])
    {
        if(d[top[x]]<d[top[y]])
        {
            ans+=putsum2(din[top[y]],din[y],1);
            y=fa[top[y]];
        }
        else
        {
            ans+=putsum2(din[top[x]],din[x],1);
            x=fa[top[x]];
        }
    }
    if(d[x]==d[y])
    {
        ans+=putsum2(din[x],din[x],1);
    }
    else if(d[x]<d[y])
    {
        ans+=putsum2(din[x],din[y],1);
    }
    else
    {
        ans+=putsum2(din[y],din[x],1);
    }
    //printf("%d\n",ans);
    put(ans);
}
int main()
{
    //freopen("xf.in","r",stdin);
    //freopen("xf.out","w",stdout);
    n=read();
    int aa,bb;
    for(int i=1;i<n;i++)
    {
        aa=read();bb=read();
        insert(aa,bb);insert(bb,aa);
    }
    for(int i=1;i<=n;i++)a[i]=read();
    d[1]=1;
    //dfs1(1);dfs2(1);
    dfs1(1,0);
    dfs2(1);
    maketree(1,n,1);
    scanf("%d",&m);
    int x,y;
    for(int i=1;i<=m;i++)
    {
        scanf("%s",s);
        x=read();y=read();
        if(s[0]=='C')chag(din[x],y,1);
        else if(s[1]=='M')putit1(x,y);
        else putsum1(x,y);
    }
    return 0;
}

  

posted @ 2018-04-10 09:41  mybing  阅读(161)  评论(0编辑  收藏  举报