萌新 合并线段树 20pts求助
查看原帖
萌新 合并线段树 20pts求助
255762
lyxleo楼主2023/2/9 19:34

板子题,但是我调不出来哪里错了,求dalao帮我看看

悬赏关注×1\times 1,感谢

#include <iostream>
#include <string.h>
using namespace std;
inline int read();
int n,m;
const int num_range = 100000;
struct Edge{
    int v,nxt;
}e[200005];
int p[100005],eid;
inline void init(){
    memset(p,-1,sizeof(p));
    eid = 0;
}
inline void insert(int u,int v){
    e[eid].v = v,e[eid].nxt = p[u],p[u] = eid++;
    return;
}
int fa[100005][25];
int d[100005];
void dfs(int u){
    d[u] = d[fa[u][0]] + 1;
    for(int i = p[u];i != -1;i = e[i].nxt){
        int v = e[i].v;
        if(v == fa[u][0]) continue;
        fa[v][0] = u;
        dfs(v);
    }
    return;
}
inline int lca(int x,int y){
    if(d[x] < d[y]) swap(x,y);
    int K = 0;
    while((1 << (K + 1)) <= d[x]) ++K;
    for(int j = K;j >= 0;--j){
        if(d[fa[x][j]] >= d[y]) x = fa[x][j];
    }
    if(x == y) return x;
    for(int j = K;j >= 0;--j){
        if(fa[x][j] != fa[y][j]) x = fa[x][j],y = fa[y][j];
    }
    return fa[x][0];
}

struct NODE{
    int l,r,maxn,maxid;
    NODE(int ll = 0,int rr = 0,int maxnn = 0,int maxidd = 0){
        l = ll,r = rr,maxn = maxnn,maxid = maxidd;
    }
};
NODE tree[12800000];
int cnt;
inline void pushup(int id){
    if(tree[tree[id].l].maxn >= tree[tree[id].r].maxn){
        tree[id].maxn = tree[tree[id].l].maxn;
        tree[id].maxid = tree[tree[id].l].maxid;
    }else{
        tree[id].maxn = tree[tree[id].r].maxn;
        tree[id].maxid = tree[tree[id].r].maxid;
    }
    return;
}
class segment{
    public:
        segment(){
            root = 0;
        }
        int root;
        void update(int &id,int l,int r,int x,int y){
            if(id == 0) id = ++cnt;
            if(l == r){
                tree[id].maxn += y;
                tree[id].maxid = x;
                return;
            }
            int mid = (l + r) >> 1;
            if(x <= mid) update(tree[id].l,l,mid,x,y);
            else update(tree[id].r,mid + 1,r,x,y);
            pushup(id);
            return;
        }
};
segment pe[100005];
int cntp;
int merge(int p,int q,int l,int r){
    //cout<<p<<" "<<q<<" "<<l<<" "<<r<<" "<<tree[p].maxn<<" "<<tree[q].maxn<<"\n";
    if(!p || !q) return p + q;
    if (l==r){
        tree[p].maxn+=tree[q].maxn;
        return p;
    }
    int mid = (l + r) >> 1;
    tree[p].l = merge(tree[p].l,tree[q].l,l,mid);
    tree[p].r = merge(tree[p].r,tree[q].r,mid + 1,r);
    pushup(p);
    return p;
}
void find(int u,int fa){
    for(int i = p[u];i != -1;i = e[i].nxt){
        int v = e[i].v;
        if(v == fa) continue;
        find(v,u);
        //if (u==1) cout<<u<<" "<<v<<" "<<pe[u].root<<" "<<pe[v].root<<'\n';
        merge(pe[u].root,pe[v].root,1,num_range);
    }
    return;
}
int main(){
    //freopen("in.in","r",stdin);
    init();
    n = read();m = read();
    for(int i = 1;i < n;++i){
        int u,v;
        u = read();v = read();
        insert(u,v);insert(v,u);
    }
    dfs(1);
    for(int j = 1;(1 << j) <= n;++j){
        for(int i = 1;i <= n;++i) fa[i][j] = fa[fa[i][j - 1]][j - 1];
    }
    while(m--){
        //cout<<"-------"<<m<<'\n';
        int x,y,kind;
        x = read();
        y = read();
        kind = read();
        int c = lca(x,y);
        int c_fa = fa[c][0];
        pe[x].update(pe[x].root,1,num_range,kind,1);
        pe[y].update(pe[y].root,1,num_range,kind,1);
        pe[c].update(pe[c].root,1,num_range,kind,-1);
        if(c_fa != 0) pe[c_fa].update(pe[c_fa].root,1,num_range,kind,-1);
    }
    find(1,-1);
    for(int i = 1;i <= n;++i){
        printf("%d\n",tree[pe[i].root].maxid);
    }
    return 0;
}

inline int read(){
    register int w = 0,flag = 1;
    register char c = getchar();
    while(c < '0' || c > '9'){
        if(c == '-') flag = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') w = (w << 3) + (w << 1) + (c ^ 48),c = getchar();
    return w * flag;
}

代码可能写的稍微有点丑……请见谅

2023/2/9 19:34
加载中...