萌新求助
查看原帖
萌新求助
368884
sunrise1024楼主2021/6/21 17:25

调傻了,样例能过,第二个点过不了

具体思路:差分+线段树合并

#include <bits/stdc++.h>
#define mid (l + r >> 1)
#define ls t[k].lc
#define rs t[k].rc
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 5;
int n, m;
vector<int> a[MAXN];
int f[MAXN][30], sh[MAXN];
/*倍增求LCA区域*/
void dfs(int no, int fa)
{
    sh[no] = sh[fa] + 1;
    f[no][0] = fa;
    for (int i = 1; i <= 30; ++i)
        f[no][i] = f[f[no][i - 1]][i - 1];
    for (int i = 0; i < a[no].size(); ++i)
    {
        if (a[no][i] != fa)
            dfs(a[no][i], no);
    }
}
int lca(int x, int y)
{
    if (sh[x] < sh[y])
        swap(x, y);
    for (int i = 28; i >= 0; --i)
    {
        if (sh[f[x][i]] >= sh[y])
            x = f[x][i];
    }
    if (x == y)
        return x;
    for (int i = 28; i >= 0; --i)
    {
        if (f[x][i] != f[y][i])
        {
            x = f[x][i];
            y = f[y][i];
        }
    }
    return f[x][0];
}
/*线段树合并删除区域*/
int tot;
struct tr
{
    int a, lc, rc, lsum, rsum;
} t[MAXN * 60];
void update(int l, int r, int k, int z, int d)
{
    if (l == r)
    {
        t[k].a += d;
        t[k].lsum = t[k].a;
        t[k].rsum = t[k].a;
        return;
    }
    if (z <= mid)
    {
        if (ls == 0)
            ls = ++tot;
        update(l, mid, ls, z, d);
    }
    else
    {
        if (rs == 0)
            rs = ++tot;
        update(mid + 1, r, rs, z, d);
    }
    t[k].lsum = max(t[t[k].lc].lsum, t[t[k].lc].rsum);
    t[k].rsum = max(t[t[k].rc].rsum, t[t[k].rc].lsum);
}
void h(int l, int r, int k1, int k2)
{
    t[k2].a += t[k1].a;
    if (t[k1].lc)
    {
        if (t[k2].lc)
        {
            h(l, mid, t[k1].lc, t[k2].lc);
        }
        else
        {
            t[k2].lc = t[k1].lc;
        }
    }
    if (t[k1].rc)
    {
        if (t[k2].rc)
        {
            h(mid + 1, r, t[k1].rc, t[k2].rc);
        }
        else
        {
            t[k2].rc = t[k1].rc;
        }
    }
    if (l == r)
    {
        t[k2].lsum = t[k2].a;
        t[k2].rsum = t[k2].a;
    }
    else
    {
        t[k2].lsum = max(t[t[k2].lc].lsum, t[t[k2].lc].rsum);
        t[k2].rsum = max(t[t[k2].rc].rsum, t[t[k2].rc].lsum);
    }
}
int query(int l, int r, int k)
{
    if (l == r)
    {
        if (t[k].a == 0)
            return 0;
        return l;
    }
    if (t[k].lsum >= t[k].rsum)
        return query(l, mid, ls);
    return query(mid + 1, r, rs);
}
void dfs1(int no, int fa)
{
    if (a[no].size() == 1)
    {
        return;
    }
    for (int i = 0; i < a[no].size(); ++i)
    {
        if (a[no][i] == fa)
            continue;
        dfs1(a[no][i], no);
        h(1, MAXN, a[no][i], no);
    }
}
int main()
{
    cin >> n >> m;
    tot = n;
    for (int i = 1; i < n; ++i)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        a[u].push_back(v);
        a[v].push_back(u);
    }
    dfs(1, 0);
    for (int i = 1; i <= m; ++i)
    {
        int x, y, z;
        scanf("%d%d%d", &x, &y, &z);
        int l = lca(x, y);
        update(1, MAXN, x, z, 1);
        update(1, MAXN, y, z, 1);
        update(1, MAXN, l, z, -1);
        if (f[l][0])
            update(1, MAXN, f[l][0], z, -1);
    }
    dfs1(1, 0);
    for (int i = 1; i <= n; ++i)
    {
        printf("%d\n", query(1, MAXN, i));
    }
    return 0;
}

顺便附上第二组数据:

in:

10 10 
2 1 
3 2 
4 3 
5 3 
6 3 
7 4 
8 5 
9 8 
10 3 
6 2 6 
3 2 6 
3 3 2 
6 6 6 
10 3 3 
10 7 1 
3 7 4 
7 9 5 
4 2 4 
3 3 6

ans:

0
6
6
4
5
6
1
5
5
1

2021/6/21 17:25
加载中...