牛客国庆集训派对Day6 I-清明梦超能力者黄YY

题解:lca预处理,树上差分套线段树合并复杂度O(nlogn)但是跑起来比树链剖分(nlognlogn)的还慢...........

​
#include"bits/stdc++.h"
#define lson l,mid,ls[rt]
#define rson mid+1,r,rs[rt]
using namespace std;
typedef long long LL;
const int MX = 1e6+7;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;
int mm,n,m,K;
vector<int> add[MX],sub[MX];
struct node{
    int u,v,c;
}p[MX];
vector<int> G[MX];
int f[MX][22], ans[MX],deep[MX];
void dfs(int u,int fa)
{
    f[u][0] = fa;
    deep[u] = deep[f[u][0]] + 1;
    for(int i = 0; f[u][i]; i++){
        f[u][i+1] = f[f[u][i]][i];
    }
    for(auto v : G[u]){
        if(v != fa) dfs(v,u);
    }
}

int lca(int x, int y)
{
    if(deep[x] < deep[y]) swap(x, y);
    for(int i = 20; i >= 0; i--)
        if(deep[f[x][i]] >= deep[y])
            x = f[x][i];
    if(x == y) return x;
    for(int i = 20; i >= 0; i--)
        if(f[x][i] != f[y][i])
            x = f[x][i], y = f[y][i];
    return f[x][0];
}

int sum[MX*20],ls[MX*20],rs[MX*20],now,rot[MX];
void push_up(int rt)
{
    sum[rt] = sum[ls[rt]] + sum[rs[rt]];
}
void update(int x, int c, int l, int r, int &rt)
{
    if(!rt) rt = ++now;
    assert(now < MX*20 && rt > 0);
    if(l == r){
        sum[rt] = c;
        return;
    }
    int mid = (l+r)>>1;
    if(x <= mid) update(x,c,lson);
    else update(x,c,rson);
    push_up(rt);
}

int query(int k, int l, int r, int rt)
{
    if(!rt) return mm;
    if(l == r) return l;
    int mid = (l+r)>>1;
    int ret = mm;
    if(sum[ls[rt]] >= k) ret = query(k,lson);
    else ret = query(k-sum[ls[rt]],rson);
    return ret;
}

int merg(int rt1, int rt2, int l, int r){
    if(!rt2) return rt1;
    if(!rt1) return rt2;
    if(l==r) return rt1;
    int mid = (l+r)>>1;
    ls[rt1] = merg(ls[rt1],ls[rt2],l,mid);
    rs[rt1] = merg(rs[rt1],rs[rt2],mid+1,r);
    push_up(rt1);
    return rt1;
}

void work(int u, int fa)
{
    for(auto v : G[u]){
        if(v == fa) continue;
        work(v,u);
        merg(rot[u],rot[v],1,mm);
    }
    for(auto id : add[u])
        update(id,1,1,mm,rot[u]);
    int id = m+1-query(K,1,mm,rot[u]);
    ans[u] = p[id].c;
    for(auto id : sub[u])
        update(id,0,1,mm,rot[u]);

}

int main()
{
    scanf("%d%d%d",&n,&m,&K);
    assert(K >= 1);
    for(int i = 1,u,v; i < n; i++){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs(1,0);
    for(int i = 1; i <= m; i++) {
        scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].c);
    }
    for(int i = m; i >= 1; i--) {
        int u = p[i].u, v = p[i].v, c = p[i].c;
        int rt = lca(u,v);
        sub[rt].push_back(m-i+1);
        if(rt != u) add[u].push_back(m-i+1);
        if(rt != v) add[v].push_back(m-i+1);
        if(u == v) add[u].push_back(m-i+1);
    }
    for(int i = 1; i <= n; i++) rot[i] = i;

    now = n;
    mm = m+1;
    work(1,0);
    for(int i = 1; i <= n; i++)
        printf("%d%c",ans[i]," \n"[i==n]);
    return 0;
}

​

猜你喜欢

转载自blog.csdn.net/qq_18869763/article/details/82953877