[Split tree chain] BZOJ3589 dynamic tree

Title Description

Do not forget that this is a dynamic tree, every moment is dynamic. Xiao Ming ask you to maintain both events this tree
Event 0:
This tree grow some fruit, namely, a sub-tree for each node in the K will grow fruit.
Event 1:

Xiao Ming hope you find the number of fruit on a few branches. Branch is actually a section of a path from a node to the root of every time Xiao Ming will select some of the branches, so that you find on these nodes in the branches of fruit and the number of Note may overlap between the branches, fruit node part of this time coincides with the long counted once.

Entry

The first line of an integer n (1 <= n <= 200,000), i.e. the number of nodes.
Next, n-1 lines of two numbers u, V. Represents a direct line between the edges of the fruit and the fruit V u. 1 are numbered starting from the node.
In a next integer nQ (1 <= nQ <= 200,000), indicates that the event.
Finally nQ lines, each line begins with either a 0 or a 1.
If it is 0, indicating that the event is an event 0. This line next two integers u, u delta means that each node is the root of the subtree delta grow a fruit.
If it is 1, indicating that this event is an event 1. This is the next line of an integer K (1 <= K <= 5), represents the inquiry involving the K branches. Then K integer u_k, v_k, from each branch u_k v_K node to node. Since the number of fruit may be very large, the output of the digital to analog results please 2 ^ 31.

Export

1, the number of fruit output for each event inquiry.

Sample input

5
1 2
2 3
2 4
1 5
3
0 1 1
0 2 3
1 2 3 1 1 4

Sample Output

13 
resolve
because it is dynamic, so give doubled LCA, consider tree chain split ( Why do trees only question in my mind these two things? ).
For events 0, x directly modify its subtree interval on dfs sequence, i.e. from x to x + siz [x] -1 plus all k.
For Event 1, the first for each chain, find its corresponding interval on dfs order, then merge these intervals, the final query to
merge the interval when the first interval sorted by ascending to the left point, then from small to large to traverse, if the current range of the right end of the next interval left point to the right of the two intervals can be combined.
There is a problem modulo 2 ^ 31, looking for Master Yi asked about the matter seems to be deep-fried int, we only need to look at the last 2 ^ 31-1 &.
code show as below
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=200005;
const int inf=2147483647;
struct node{int l,r;}q[maxn];
int en,mk[maxn<<2],sum[maxn<<2];
int n,Q,id,info[maxn],nx[maxn<<1],v[maxn<<1];
int fa[maxn],dep[maxn],dfn[maxn],siz[maxn],son[maxn],top[maxn];
bool cmp(node a,node b){return a.l==b.l?a.r<b.r:a.l<b.l;}
void add(int u1,int v1){nx[++id]=info[u1];info[u1]=id;v[id]=v1;}
void dfs1(int x,int f)
{
    dep[x]=dep[fa[x]=f]+(siz[x]=1);
    for(int i=info[x];i;i=nx[i])if(v[i]!=f)
    {
        dfs1(v[i],x);siz[x]+=siz[v[i]];
        if(siz[v[i]]>siz[son[x]])son[x]=v[i];
    }
}
void dfs2(int x,int f)
{
    dfn[x]=++id;top[x]=f;if(son[x])dfs2(son[x],f);
    for(int i=info[x];i;i=nx[i])if(v[i]!=fa[x]&&v[i]!=son[x])dfs2(v[i],v[i]);
}
void pushdown(int id,int l,int r)
{
    int mid=(l+r)/2;
    mk[id*2]+=mk[id];mk[id*2+1]+=mk[id];
    sum[id*2]+=(mid-l+1)*mk[id];sum[id*2+1]+=(r-mid)*mk[id];mk[id]=0;
}
void fix(int id,int l,int r,int l1,int r1,int k)
{
    if(r1<l||r<l1)return;
    if(l1<=l&&r<=r1){sum[id]+=k*(r-l+1);mk[id]+=k;return;}
    pushdown(id,l,r);int mid=(l+r)/2;
    fix(id*2,l,mid,l1,r1,k);fix(id*2+1,mid+1,r,l1,r1,k);sum[id]=sum[id*2]+sum[id*2+1];
}
int que(int id,int l,int r,int l1,int r1)
{
    if(r1<l||r<l1)return 0;
    if(l1<=l&&r<=r1)return sum[id];
    pushdown(id,l,r);int mid=(l+r)/2;
    return que(id*2,l,mid,l1,r1)+que(id*2+1,mid+1,r,l1,r1);
}
int main()
{
    scanf("%d",&n);
    for(int i=1,u1,v1;i<n;i++)scanf("%d%d",&u1,&v1),add(u1,v1),add(v1,u1);
    id=0;dfs1(1,0);dfs2(1,1);id=0;
    scanf("%d",&Q);
    for(int i=1,ord,x,k;i<=Q;i++)
    {
        scanf("%d",&ord);
        if(ord==0)scanf("%d%d",&x,&k),fix(1,1,n,dfn[x],dfn[x]+siz[x]-1,k);
        if(ord==1)
        {
            scanf("%d",&k);en=0;
            for(int i=1,a,b;i<=k;i++)
            {
                scanf("%d%d",&a,&b);
                if(dep[b]>dep[a])swap(a,b);
                while(top[a]!=top[b])q[++en]=(node){dfn[top[a]],dfn[a]},a=fa[top[a]];
                q[++en]=(node){dfn[b],dfn[a]};
            }
            sort(q+1,q+1+en,cmp);
            int ans=0;
            for(int i=1,l,r;i<=en;i++)
            {
                l=q[i].l,r=q[i].r;
                while(q[i+1].l<=r&&i+1<=en)r=max(q[i+1].r,r),i++;
                ans+=que(1,1,n,l,r);
            }
            printf("%d\n",ans&inf);
        }
    }
}
 
  

 

 

Guess you like

Origin www.cnblogs.com/firecrazy/p/11512430.html