Tail solution to a problem bzoj3307 rain (+ segment tree merge trees differential)

Description

N points, form a tree structure. There are M times issuing, selecting two points each x, y
for the x-y path (including x, y) of each point sent a bag Z types of items. Completion of
all the issued, each point store up to what kind of items.

Input

The first row of numbers N, M
the next N-1 lines of two numbers a, b, indicates there is an edge between a and b,
then the next M rows, each row of three numbers x, y, z. If that

Output

There are N rows of the output
digital representation for each row i of the i th point is stored items which most, if there is
the same number of a variety of articles, the minimum output number. If an item does not point
output 0

 

 

See the tree path to operate (in konjac blogger current level of knowledge) is nothing more than two choices, sectional tree / tree differential

But in the end asked only once if the difference chapter is a better choice

And we want to operate not only the right to make changes to the value of the point, but the insertion of the new weights for each point and count the number of outstanding

This time should expect the right to build value for each segment tree node to maintain information

Such differential operation on the use of weights segment tree insert operation to solve

 

However, when the geese in the final statistical information to be merged subtree

So it needs to merge tree line

 

 

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=100005;
int n,m,to[N<<1],nxt[N<<1],head[N],tot=0;
int size[N*50],type,root[N],ls[N*50],rs[N*50],fa[N][22],dep[N],now[N*50],ans[N];
void add(int x,int y)
{
    to[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9')
    {if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')
    {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    return x*f;
}
void dfs(int x,int deep)
{
    dep[x]=deep;
    for(int i=1;i<=20;i++)
        four [x] [c] = four [four [x] [p 1 ]] [p 1 ];
    for ( int on = Head [x]; in; at = nxt [c])
    {
        if(dep[to[i]])continue;
        fa[to[i]][0]=x;
        dfs(to[i],deep+1);
    }
}
int lca(int x,int y)
{
    if(dep[x]>dep[y])swap(x,y);
    for(int i=20;i>=0;i--)
        if(dep[fa[y][i]]>=dep[x])y=fa[y][i];
    if(x==y)return x;
    for(int i=20;i>=0;i--)
        if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
    return fa[x][0];
}
void up(int x)
{
    if(size[ls[x]]>=size[rs[x]])
    {
        size[x]=size[ls[x]];
        now[x]=now[ls[x]];
    }
    else 
    {
        size[x]=size[rs[x]];
        now[x]=now[rs[x]];
    }
}
void add(int &k,int l,int r,int val,int num)
{
    if(!k)k=++type;
    if(l==r)
    {
        size[k]+=num;
        now[k]=l;
        return ;
    }
    int mid=l+r>>1;
    if(val<=mid)add(ls[k],l,mid,val,num);
    else add(rs[k],mid+1,r,val,num);
    up(k);
    return ;
}
you Merge ( you get, you y, you're with, you r)
{
    if(!x||!y)return x+y;
    if(l==r)
    {
        size[x]=size[x]+size[y];
        now[x]=l; 
        return x;
    }
    int mid=l+r>>1;
    ls[x]=Merge(ls[x],ls[y],l,mid);
    rs[x]=Merge(rs[x],rs[y],mid+1,r);
    up(x);
    return x;
}
void cacl(int x)
{
    for(int i=head[x];i;i=nxt[i])
    {
        if(to[i]==fa[x][0])continue;
        cacl(to[i]);
        root[x]=Merge(root[x],root[to[i]],1,N-5);
    }
    if(now[root[x]])ans[x]=now[root[x]];
    else ans[x]=0;
}
int main ()
{
    n=read();m=read();
    for(int i=1;i<n;i++)
    {
        int x=read(),y=read();
        add(x,y);add(y,x);
    }
    dfs(1,1);
    for(int i=1;i<=m;i++)
    {
        int x=read(),y=read(),z=read();
        int LCA=lca(x,y);//cout<<"///"<<LCA<<endl;
        add(root[x],1,N-5,z,1);
        add(root[y],1,N-5,z,1);
        add(root[LCA],1,N-5,z,-1);
        add(root[fa[LCA][0]],1,N-5,z,-1);
    }
    cacl(1);
    for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
    return 0;
}

 

 

 

 

Guess you like

Origin www.cnblogs.com/Rorschach-XR/p/11032252.html