关于动态开点线段树的两种写法
查看原帖
关于动态开点线段树的两种写法
770611
xxxxxzy楼主2023/11/25 22:03

两份不同的修改的代码,一份AC,一份WA 10 分

有没有大佬可以说一下WA的那份哪里有问题吗

//AC
void add(int &p, int l, int r, int k, int d) {
    if (p == 0) p = ++tot;
    if (l == r) {
        tt[p].dat += d;
        tt[p].mx=k;
        return;
    }
    int mid = (l + r) >> 1;
    if (k <= mid) add(tt[p].lc, l, mid, k, d);
    else add(tt[p].rc, mid + 1, r, k, d);
    pushup(p);
}
//Wa 10
//下边有一行 for (int i = 1; i <= n; i++) root[i] = build();
int build() {
    tt[++tot].lc = tt[tot].rc = tt[tot].dat = 0;
    return tot;
}
void add(int p, int l, int r, int k, int d) {
    if (l == r) {
        tt[p].dat += d;
        tt[p].mx=k;
        return;
    }
    int mid = (l + r) >> 1;
    if (k <= mid) {
        if (!tt[p].lc) tt[p].lc = build();
        add(tt[p].lc, l, mid, k, d);
    } else if (k > mid){
        if (!tt[p].rc) tt[p].rc = build();
        add(tt[p].rc, mid + 1, r, k, d);
    }
    pushup(p);
}

完整代码:

//Wa 10
//AC代码只用如上替换即可
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, m, p, d[100005], t, f[100005][25], tot, root[100005];
vector<int> ed[100005];
map<int, int> cnt;
int to[100005];
struct segmentTree {
    int lc, rc, maxn, dat, mx, x;
}tt[3000005];
int build() {
    tt[++tot].lc = tt[tot].rc = tt[tot].dat = 0;
    return tot;
}
void pushup(int x){
	int lx=tt[x].lc,rx=tt[x].rc;
	if(tt[lx].dat==0) tt[x].dat=tt[rx].dat,tt[x].mx=tt[rx].mx;
	else if(tt[rx].dat==0) tt[x].dat=tt[lx].dat,tt[x].mx=tt[lx].mx;
	else if(tt[lx].dat>=tt[rx].dat) tt[x].dat=tt[lx].dat,tt[x].mx=tt[lx].mx;
	else tt[x].dat=tt[rx].dat,tt[x].mx=tt[rx].mx;
}
void add(int p, int l, int r, int k, int d) {
    if (l == r) {
        tt[p].dat += d;
        tt[p].mx=k;
        return;
    }
    int mid = (l + r) >> 1;
    if (k <= mid) {
        if (!tt[p].lc)
            tt[p].lc = build();
        add(tt[p].lc, l, mid, k, d);
    } else if (k > mid){
        if (!tt[p].rc)
            tt[p].rc = build();
        add(tt[p].rc, mid + 1, r, k, d);
    }
    pushup(p);
}
int merge(int p, int q, int l, int r) {
    if (!p||!q) return q|p;
    if (l == r) {
        tt[p].dat += tt[q].dat;
        return p;
    }
    int mid = (l + r) >> 1;
    tt[p].lc = merge(tt[p].lc, tt[q].lc, l, mid);
    tt[p].rc = merge(tt[p].rc, tt[q].rc, mid + 1, r);
    pushup(p);
    return p;
}
void dfsn(int u, int fa){
    f[u][0]=fa;
    d[u]=d[fa]+1;
    for(int i=1;i<24;++i) f[u][i]=f[f[u][i-1]][i-1];
    for(int i=0;i<ed[u].size();i++){
        int v=ed[u][i];
        if(v==fa) continue;
        dfsn(v, u);
    }
}
int lca(int x, int y) {
    if (d[x] > d[y])
        swap(x, y);
    for (int i = t; i >= 0; i--) {
        if (d[f[y][i]] >= d[x])
            y = f[y][i];
    }
    if (x == y)
        return x;
    for (int i = t; i >= 0; i--) {
        if (f[x][i] != f[y][i])
            x = f[x][i], y = f[y][i];
    }
    return f[x][0];
}
int ans[100005];
void dfs(int x, int fa) {
    for (int i = 0; i < ed[x].size(); i++) {
        int y = ed[x][i];
        if (y == fa)
            continue;
        dfs(y, x);
        root[x]=merge(root[x], root[y], 1, p);
    }
    ans[x] = to[tt[root[x]].mx];
    if(tt[root[x]].dat==0) ans[x]=0;
}
struct query{
	int x,y,z;
}op[100005];
bool cmp(query a,query b){
	return a.z<b.z;
}
signed main() {
    cin >> n >> m;
    t = 23;
    for (int i = 1; i < n; i++) {
        int u, v;
        cin >> u >> v;
        ed[u].push_back(v);
        ed[v].push_back(u);
    }
    dfsn(1,0);
    for (int i = 1; i <= m; i++) cin >>op[i].x>>op[i].y>>op[i].z;
    sort(op+1,op+1+m,cmp);
    for(int i=1;i<=m;i++){
    	if(!cnt[op[i].z])
       		cnt[op[i].z] = ++p, to[p] = op[i].z;
		op[i].z = cnt[op[i].z];
	}
//	for(int i=1;i<=p;i++) cout<<i<<" "<<to[i]<<endl;
    for (int i = 1; i <= n; i++) root[i] = build();
    for (int i = 1; i <= m; i++) {
    	int Lca=lca(op[i].x,op[i].y);
        add(root[op[i].x], 1, p, op[i].z, 1);
        add(root[op[i].y], 1, p, op[i].z, 1);
        add(root[Lca], 1, p, op[i].z, -1);
        add(root[f[Lca][0]], 1, p, op[i].z, -1);
//        cout<<op[i].x<<" "<<op[i].y<<" "<<lca(op[i].x, op[i].y)<<endl;
    }
    dfs(1,0);
    for (int i = 1; i <= n; i++) {
        cout << ans[i] << endl;
    }
}
2023/11/25 22:03
加载中...