ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

N个点,形成一个树状结构。有M次发放,每次选择两个点x,y
对于x到y的路径上(含x,y)每个点发一袋Z类型的物品。完成
所有发放后,每个点存放最多的是哪种物品。

Input

第一行数字N,M
接下来N-1行,每行两个数字a,b,表示a与b间有一条边
再接下来M行,每行三个数字x,y,z.如题

Output

输出有N行
每i行的数字表示第i个点存放最多的物品是哪一种,如果有
多种物品的数量一样,输出编号最小的。如果某个点没有物品
则输出0

离线处理,树链剖分将树展开为链,然后对操作记录差分(当前点比上一个点多了、少了哪些物品)

最后扫一遍处理出答案

#include<cstdio>
#include<algorithm>
#include<vector>
int read(){
    int x=0,c=getchar();
    while(c<48)c=getchar();
    while(c>47)x=x*10+c-48,c=getchar();
    return x;
}
const int N=100010;
int n,m;
int et[N*2],enx[N*2],e0[N],ep=2;
int sz[N],dep[N],fa[N],pf[N],top[N],id[N],idr[N],idp=0;
int q[N][3],vs[N],t[N],tr[262144],ans[N];
std::vector<int> _i[N],_d[N];
void f1(int w,int pa){
    dep[w]=dep[fa[w]=pa]+1;
    sz[w]=1;
    for(int i=e0[w];i;i=enx[i]){
        int u=et[i];
        if(u==pa)continue;
        f1(u,w);
        sz[w]+=sz[u];
        if(sz[u]>sz[pf[w]])pf[w]=u;
    }
}
void f2(int w,int tp){
    idr[id[w]=++idp]=w;
    top[w]=tp;
    if(pf[w])f2(pf[w],tp);
    for(int i=e0[w];i;i=enx[i]){
        int u=et[i];
        if(u!=fa[w]&&u!=pf[w])f2(u,u);
    }
}
void ins(int x,int y,int z){
    int a=top[x],b=top[y],c;
    while(a!=b){
        if(dep[a]<dep[b])c=a,a=b,b=c,c=x,x=y,y=c;
        _i[id[a]].push_back(z);
        _d[id[x]].push_back(z);
        x=fa[a];a=top[x];
    }
    if(dep[x]>dep[y])c=x,x=y,y=c;
    _i[id[x]].push_back(z);
    _d[id[y]].push_back(z);
}
void _ins(int x){
    ++t[x];
    int w=x+131072;
    tr[w]=x;
    for(w>>=1;w;w>>=1){
        int a=w<<1,b=a^1;
        tr[w]=t[tr[b]]>t[tr[a]]?tr[b]:tr[a];
    }
}
void _del(int x){
    int w=x+131072;
    if(!--t[x])tr[w]=0;
    for(w>>=1;w;w>>=1){
        int a=w<<1,b=a^1;
        tr[w]=t[tr[b]]>t[tr[a]]?tr[b]:tr[a];
    }
}
int main(){
    n=read();m=read();
    for(int i=1;i<n;i++){
        int a=read(),b=read();
        et[ep]=b;enx[ep]=e0[a];e0[a]=ep++;
        et[ep]=a;enx[ep]=e0[b];e0[b]=ep++;
    }
    f1(1,0);f2(1,1);
    for(int i=0;i<m;i++){
        q[i][0]=read();
        q[i][1]=read();
        vs[i]=q[i][2]=read();
    }
    std::sort(vs,vs+m);
    for(int i=0;i<m;i++){
        ins(q[i][0],q[i][1],std::lower_bound(vs,vs+m,q[i][2])-vs+1);
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<_i[i].size();j++)_ins(_i[i][j]);
        ans[idr[i]]=tr[1]?vs[tr[1]-1]:0;
        for(int j=0;j<_d[i].size();j++)_del(_d[i][j]);
    }
    for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
    return 0;
}

 

posted on 2016-07-29 18:15  nul  阅读(361)  评论(0编辑  收藏  举报