Statistics Count [ZJOI2008] tree: BZOJ1036

Description

  A tree of n nodes, numbered 1 to n, each node has a weight value w. We will take the following form to ask you this tree to perform some action: I. CHANGE ut: the junction of u right value to t II QMAX uv:. Nodes on the inquiry from point u to point v path the maximum weight III QSUM uv:. inquiry node u from point to point on the path weights and v Note: from point to point on the path node u v and v u itself comprises

Input

  A first act input integer n, the number of nodes. Next, n - 1 lines of two integers a and B, expressed an edge connected between the node a and node b. Next n lines, each line an integer, the integer i-th row wi represents the weight of the node i. The next line 1, is an integer q, the total number of representations of operations. Next q lines of operation are given in the form of "CHANGE ut" or "QMAX uv" or "QSUM uv" is. 
To 100% of the data, to ensure that 1 <= n <= 30000,0 < = q <= 200000; middle weights w ensure operation of each node between -30000 and 30000.

Output

  For each operation "QMAX" or "QSUM", the output of each row represents an integer result output requirements.

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
 
Tree chain split 
point right single point modified segment tree maintenance interval maximum value, and
#include <bits / STDC ++ H.>
 #define ULL unsigned Long Long
 the using  namespace STD;
 const  int N = 1E5 + 100 ;
 int n-, m, TOT, CNT;
 int FA [N], Last [N];
 int Son [N ], deep [N], DFN [N], NUM [N], top [N]; // end node re-order sub-tree dfs son depth scale where the heavy chain 
int SUM [N * . 4 ], MX [N * . 4 ], W [N];
 struct orz {
     int V, NEX;} E [N];
 char OP [ 10 ];
 void the init () 
{ 
    CNT = 0 ; 
    TOT =0;
    memset(last,0,sizeof(last));
    memset(son,-1,sizeof(son));
}
void Insert(int x,int y)
{
    cnt++;
    e[cnt].v=y;
    e[cnt].nex=last[x];
    last[x]=cnt;
}
void dfs1(int x,int d,int pre)
{
    fa[x]=pre;
    deep[x]=d;
    num[x]=1;
    for (int i=last[x];i;i=e[i].nex)
    {
        int v=e[i].v;
        if (v==fa[x]) continue;
        dfs1(v,d+1,x);
        num[x]+=num[v];
        if (son[x]==-1 || num[v]>num[son[x]]) son[x]=v;
    }
}
void dfs2(int x,int sp)
{
    top[x]=sp;
    dfn[x]=++tot;
    if (son[x]==-1) return ;
    dfs2(son[x],sp);
    for (int i=last[x];i;i=e[i].nex)
    {
        int v=e[i].v;
        if (v==fa[x]) continue;
        if (v!=son[x]) dfs2(v,v);
    }
}
void PushUp(int s)
{
    sum[s]=sum[s<<1]+sum[s<<1|1];
    mx[s]=max(mx[s<<1],mx[s<<1|1]);
}
void build(int s,int l,int r)
{
    mx[s]=sum[s]=0;
    if (l==r) return ;
    int m=(l+r)>>1;
    build(s<<1,l,m); build(s<<1|1,m+1,r);
    PushUp(s);
}
void update(int s,int l,int r,int pos,int val)
{
    if (l==r)
    {
        mx[s]=sum[s]=val;
        return ;
    }
    int mid=(l+r)>>1;
    if (pos<=mid) update(s<<1,l,mid,pos,val);
    else update(s<<1|1,mid+1,r,pos,val);
    PushUp(s);
}
int querymx(int s,int l,int r,int L,int R)
{
    //printf("s=%d,l=%d,r=%d,L=%d,R=%d\n",s,l,r,L,R);
    if (L<=l&&r<=R) return mx[s];
    int mid=(l+r)>>1;
    int ans=INT_MIN;
    if (L<=mid) ans=max(ans,querymx(s<<1,l,mid,L,R));
    if (R>mid) ans=max(ans,querymx(s<<1|1,mid+1,r,L,R));
    return ans;
}
int querysum(int s,int l,int r,int L,int R)
{
    if (L<=l&&r<=R) return sum[s];
    int mid=(l+r)>>1;
    int ans=0;
    if (L<=mid) ans+=querysum(s<<1,l,mid,L,R);
    if (R>mid) ans+=querysum(s<<1|1,mid+1,r,L,R);
    return ans;
}
void solve(int op,int x, int y)
{
    if (op==1)
    {
        int mx=INT_MIN;
        while (top[x]!=top[y])
        {
            if (deep[top[x]]<deep[top[y]]) swap(x, y);
            mx=max(mx,querymx(1,1,n,dfn[top[x]],dfn[x]));
            x=fa[top[x]];
        }
        if (deep[x]>deep[y]) swap(x,y);
        mx=max(mx,querymx(1,1,n,dfn[x],dfn[y]));
        printf("%d\n",mx);
    }
    else
    {
        int ans=0;
        while (top[x]!=top[y])
        {
            if (deep[top[x]]<deep[top[y]]) swap(x, y);
            ans+=querysum(1,1,n,dfn[top[x]],dfn[x]);
            x=fa[top[x]];
        }
        if (deep[x]>deep[y]) swap(x,y);
        ans+=querysum(1,1,n,dfn[x],dfn[y]);
        printf("%d\n",ans);
    }
}

int main()
{
    while (scanf("%d",&n)!=EOF)
    {
        init();
        int u,v;
        for (int i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            Insert(u,v);
            Insert(v,u);
        }
        dfs1(1,0,0); //cout<<'*'<<endl;
        dfs2(1,1);

        build(1,1,n);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&u);
            update(1,1,n,dfn[i],u);
        }
        scanf("%d",&m);

        while (m--)
        {
            scanf("%s",op);
            if (op[0]=='C')
            {
                scanf("%d%d",&u,&v);
                update(1,1,n,dfn[u],v);
            }
            else
            {
                scanf("%d%d",&u,&v);
                if (op[1]=='M') solve(1,u,v);
                else solve(2,u,v);
            }
        }
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/tetew/p/11293927.html