CH6302 rain tail

background

Eri has been deep hate rain.
Hot weather penetrate the first half of the summer, then a heavy rain and consequent flooding, extinguished everything.
Although deep Eri home has a small village on the flood stubborn resistance, but also several old houses collapsed, trees were uprooted trees, and fields of grain are confused mess.
Eri deep frustration and villagers had to wait for relief food to subsist.
But relief food is distributed very special way.

description

There are N (N≤10 ^ 5) points form a tree structure.
There are M (M≤10 ^ 5) issuing operation times, each time selecting two points x, y, for each point on the path from x to y (including x, y) issuance bag z (z≤10 ^ 9 ) types of items.
After the completion of all required payment operations, each point store up to what type of items.

Input Format

The first line of two positive integers n, m, the meaning of the subject as shown in FIG.
Next, n-1 lines of two numbers (a, b), indicates there is an edge (a, b) between.
The next m lines of three numbers (x, y, z), the meaning of the subject as shown in FIG.

Output Format

n rows, an integer i-th row, representing the largest houses in the first i kind of relief food storage, if there are a variety of relief food storage times, like minimum output number.
If there are no houses a relief food, a line of output corresponds to 0.

Sample input

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

Sample Output

2
3
3
0
2

Data range and Conventions

  • For 20% of the data, 1 <= n, m <= 100
  • For 50% of the data, 1 <= n, m <= 2000
  • To 100% of the data, 1 <= n, m <= 100000, 1 <= a, b, x, y <= n, 1 <= z <= 100000

source

Vani, Vani have an appointment Cup Tournament

answer

Tree can be used for differential counting articles, each article in the x, y + 1 at, at lca, fa [lca] to cm⁻¹.
Use space segment tree merge to solve the problem. Time complexity \ (O (n \ log n ) \)

To practice tarjan seeking lca.

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;rg char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
    for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
    return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std;

co int N=1e5+1;
int n,m;
// tarjan lca
vector<int> e[N];
int x[N],y[N],z[N],val[N],cnt;
vector<pair<int,int> > q[N];
int vis[N],pa[N],lca[N],fa[N]; // pa for disjoint set,fa for real father
int find(int x) {return pa[x]==x?x:pa[x]=find(pa[x]);}
void tarjan(int x){
    vis[x]=1;
    for(int i=0,y;i<e[x].size();++i){
        if(vis[y=e[x][i]]) continue;
        tarjan(y);
        pa[y]=fa[y]=x;
    }
    for(int i=0,y;i<q[x].size();++i)
        if(vis[y=q[x][i].first]==2)
            lca[q[x][i].second]=find(y);
    vis[x]=2;
}
// Interval Tree
int tot,lc[N*72],rc[N*72],dat[N*72],pos[N*72];
void insert(int&x,int l,int r,int p,int d){
    if(!x) x=++tot;
    if(l==r){
        dat[x]+=d,pos[x]=dat[x]?l:0;
        return;
    }
    int mid=l+r>>1;
    if(p<=mid) insert(lc[x],l,mid,p,d);
    else insert(rc[x],mid+1,r,p,d);
    if(dat[lc[x]]>=dat[rc[x]])
        dat[x]=dat[lc[x]],pos[x]=pos[lc[x]];
    else
        dat[x]=dat[rc[x]],pos[x]=pos[rc[x]];
}
int merge(int x,int y,int l,int r){
    if(!x||!y) return x+y;
    if(l==r){
        dat[x]+=dat[y],pos[x]=dat[x]?l:0;
        return x;
    }
    int mid=l+r>>1; // edit 1: >>
    lc[x]=merge(lc[x],lc[y],l,mid);
    rc[x]=merge(rc[x],rc[y],mid+1,r);
    if(dat[lc[x]]>=dat[rc[x]])
        dat[x]=dat[lc[x]],pos[x]=pos[lc[x]];
    else
        dat[x]=dat[rc[x]],pos[x]=pos[rc[x]];
    return x;
}

int root[N],ans[N];
void dfs(int x){
    for(int i=0,y;i<e[x].size();++i){
        if((y=e[x][i])==fa[x]) continue;
        dfs(y);
        root[x]=merge(root[x],root[y],1,cnt);
    }
    ans[x]=pos[root[x]];
}
int main(){
//  freopen("CH6302.in","r",stdin),freopen("CH6302.out","w",stdout);
    read(n),read(m);
    for(int i=1,x,y;i<n;++i){
        read(x),read(y);
        e[x].push_back(y),e[y].push_back(x);
    }
    for(int i=1;i<=m;++i){
        read(x[i]),read(y[i]),val[i]=read(z[i]);
        if(x[i]==y[i]) lca[i]=x[i];
        else q[x[i]].push_back(make_pair(y[i],i)),q[y[i]].push_back(make_pair(x[i],i));
    }
    for(int i=1;i<=n;++i) pa[i]=i;
    tarjan(1);
    sort(val+1,val+m+1),cnt=unique(val+1,val+m+1)-val-1;
    for(int i=1;i<=m;++i){
        z[i]=lower_bound(val+1,val+cnt+1,z[i])-val;
//      cerr<<i<<" lca="<<lca[i]<<endl;
        insert(root[x[i]],1,cnt,z[i],1);
        insert(root[y[i]],1,cnt,z[i],1);
        insert(root[lca[i]],1,cnt,z[i],-1);
        if(fa[lca[i]]) insert(root[fa[lca[i]]],1,cnt,z[i],-1);
    }
    dfs(1);
    for(int i=1;i<=n;++i) printf("%d\n",val[ans[i]]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/autoint/p/10930216.html