貌似是取模的问题,奇怪
查看原帖
貌似是取模的问题,奇怪
722021
aHapBean楼主2022/10/6 11:55

目前70pts,剩三个大数据点没过,对着数据点2的数据调了半天的取模,还是错的

目前我也不清楚是哪里的问题,暂时没看出树剖和线段树的逻辑问题,所以我暂且认为是取模的问题。

求帮忙看看,我自己同时也会找

谢谢,orz

#define fileopen freopen("in","r",stdin);cout << "freopen here" << endl
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1e5 + 10;
int n,m,r,MOD;
int son[maxn],vis[maxn],siz[maxn],depth[maxn],f[maxn];
int top[maxn],dfn[maxn],rdfn[maxn],val[maxn];
int sum[maxn << 2],lz[maxn << 2];
int fst[maxn],nxt[maxn << 1];
struct edge{
    int u,v;
}side[maxn << 1];
int tnt,cnt;
void dfs1(int u) {
    son[u] = -1;
    siz[u] += 1;
    for(int i = fst[u]; i; i = nxt[i]) {
        int v = side[i].v;
        if(!depth[v]) {
            depth[v] = depth[u] + 1;
            f[v] = u;
            dfs1(v);
            siz[u] += siz[v];
            if(son[u] == -1 || siz[son[u]] < siz[v])
                son[u] = v;
        }
    }
}
void dfs2(int u,int t) {
    top[u] = t;
    dfn[u] = ++tnt;
    rdfn[tnt] = u;
    if(son[u] == -1)
        return ;
    dfs2(son[u],t);
    for(int i = fst[u]; i; i = nxt[i]) {
        int v = side[i].v;
        if(son[u] != v && v != f[u])
            dfs2(v,v);
    }
}
void add(int u,int v) {
    side[++cnt] = {u,v};
    nxt[cnt] = fst[u];
    fst[u] = cnt;
}
void build(int rt,int l,int r) {
    if(l == r) {
        sum[rt] = (sum[rt] + val[rdfn[l]]) % MOD;
        return ;
    }
    int m = l + r >> 1;
    build(rt << 1,l,m);
    build(rt << 1 | 1,m + 1,r);
    sum[rt] = (sum[rt << 1] + sum[rt << 1 | 1]) % MOD;
}
void pushdown(int rt,int l,int r) {
    if(lz[rt] == 0)
        return ;
    lz[rt] %= MOD;
    int m = l + r >> 1;
    lz[rt << 1] += lz[rt];
    lz[rt << 1] %= MOD;
    lz[rt << 1 | 1] += lz[rt];
    lz[rt << 1 | 1] %= MOD;
    sum[rt << 1] = ((sum[rt << 1] + 1ll * lz[rt] * (m - l + 1) % MOD) % MOD + MOD) % MOD;
    sum[rt << 1 | 1] = ((sum[rt << 1 | 1] + 1ll * lz[rt] * (r - m - 1 + 1) % MOD) + MOD) % MOD;
    lz[rt] = 0;
}
void update(int rt,int l,int r,int x,int y,int k) {
    pushdown(rt,l,r);
    if(x <= l && r <= y) {
        k %= MOD;
        lz[rt] += k;lz[rt] %= MOD;
        sum[rt] = (sum[rt] + 1ll * k * (r - l + 1) % MOD) % MOD;
        return ;
    }
    int m = l + r >> 1;
    if(x <= m) update(rt << 1,l,m,x,y,k);
    if(y > m) update(rt << 1 | 1,m + 1,r,x,y,k);    //here fuck
    sum[rt] = ((sum[rt << 1] % MOD + sum[rt << 1 | 1] % MOD) + 2ll * MOD) % MOD;
}
void upd_chain(int x,int y,int k) {
    k %= MOD;
    while(top[x] != top[y]) {
        if(depth[top[x]] < depth[top[y]]) 
            swap(x,y);
        update(1,1,n,dfn[top[x]],dfn[x],k);
        x = f[top[x]];
    }
    if(depth[x] < depth[y])
        swap(x,y);
    update(1,1,n,dfn[y],dfn[x],k);  //  here
}
int query(int rt,int l,int r,int x,int y) {
    pushdown(rt,l,r);
    if(x <= l && r <= y) {
        return sum[rt] % MOD;
    }
    int m = l + r >> 1;
    ll ret = 0;
    if(x <= m) ret += query(rt << 1,l,m,x,y) % MOD;
    if(y > m) ret += query(rt << 1 | 1,m + 1,r,x,y) % MOD;
    return ret % MOD;
}
int query_chain(int x,int y) {
    ll ret = 0;
    while(top[x] != top[y]) {
        if(depth[top[x]] < depth[top[y]]) 
            swap(x,y);
        ret += query(1,1,n,dfn[top[x]],dfn[x]) % MOD;
        ret %= MOD;
        x = f[top[x]];
    }
    if(depth[x] < depth[y])
        swap(x,y);
    ret += query(1,1,n,dfn[y],dfn[x]) % MOD;
    return ret % MOD;
}
int main() {
    fileopen;
    freopen("my_ans","w",stdout);
    cin >> n >> m >> r >> MOD;
    for(int i = 1; i <= n; ++i)
        scanf("%d",val + i);
    for(int i = 0; i < n - 1; ++i) {
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);add(v,u);
    }
    for(int i = 1; i <= n; ++i)
        f[i] = i;
    depth[r] = 1;
    dfs1(r);
    dfs2(r,r);
    build(1,1,n);
    int flag,a,b,c;
    for(int i = 0; i < m; ++i) {
        scanf("%d",&flag);
        if(flag == 1) {
            scanf("%d%d%d",&a,&b,&c);
            upd_chain(a,b,c);
        } else if(flag == 4) {
            scanf("%d",&a);
            printf("%d\n",(query(1,1,n,dfn[a],dfn[a] + siz[a] - 1) % MOD + MOD) % MOD);
        } else {
            scanf("%d%d",&a,&b);
            if(flag == 2) {
                printf("%d\n",query_chain(a,b));
            } else {
                update(1,1,n,dfn[a],dfn[a] + siz[a] - 1,b);
            }
        }
    }
    return 0;
}
2022/10/6 11:55
加载中...