50分求助

P7077 [CSP-S2020] 函数调用

Anakin_XYLei @ 2021-09-28 21:28:44

大致思路和第一篇题解相同,但找不出有什么问题。

#include <bits/stdc++.h>
const int N = 1e5+5, M=1e6+6, MOD=998244353;
typedef long long ll;
int n,m;
int a[N];

int he[N],te[N],ne[M],pe[M],ve[M],idx=1;
int ind[N];
void addE(int x,int y) {
    idx++,ind[y]++;
    if (!te[x]) te[x]=idx;
    ve[idx]=y,ne[idx]=he[x],pe[he[x]]=idx,he[x]=idx;
}

int tp[N],add[N],pos[N];
int mul[N],tot[N];

int op1[N],p;

void input() {
    static int stmp[M];
    scanf("%d",&n);

    for (int i=1;i<=n;i++) {scanf("%d",&a[i]);}
    scanf("%d",&m);
    mul[0]=1;
    for (int i=1;i<=m;i++) {
        scanf("%d",&tp[i]);
        mul[i]=1;
        if (tp[i]==1) {
            op1[++p]=i;
            scanf("%d%d",&pos[i],&add[i]);
        }
        else if (tp[i]==2) {
            scanf("%d",&mul[i]);
        }
        else {
            int cnt;
            scanf("%d",&cnt);
            for (int j=1;j<=cnt;j++) {
                scanf("%d",&stmp[j]);
            }
            for (int j=cnt;j>=1;j--) {
                addE(i,stmp[j]);
            }
        }
    }
    int cnt;
    scanf("%d",&cnt);
    for (int j=1;j<=cnt;j++) {
        scanf("%d",&stmp[j]);
    }
    for (int j=cnt;j>=1;j--) {
        addE(0,stmp[j]);
    }
}

void dfs(int x) {
    static bool st[N];
    if (st[x]) return ;
    st[x]=1;
    for (int i=he[x];i;i=ne[i]) {
        int y=ve[i];
        dfs(y);
        mul[x]=(ll)mul[x]*mul[y]%MOD;
    }
}

void toposort() {
    std::queue<int> q;
    tot[0]=1;
    q.push(0);
    while (!q.empty()) {
        int x=q.front();q.pop();
        int now_mul=1;
        for (int i=te[x];i;i=pe[i]) {
            int y=ve[i];
            tot[y]=((ll)tot[x]*now_mul%MOD+tot[y])%MOD;
            now_mul=(ll)mul[y]*now_mul%MOD;
            ind[y]--;
            if (ind[y]==0) q.push(y);
        }
    }
}

int main() {
    input();
    dfs(0);
    toposort();

    for (int i=1;i<=n;i++) {
        a[i]=(ll)a[i]*mul[0]%MOD;
    }

    for (int i=1;i<=p;i++) {
        int x=op1[i];
        a[pos[x]]=((ll)add[x]*tot[x]%MOD+a[pos[x]])%MOD;
    }

    for (int i=1;i<=n;i++) printf("%d ",a[i]%MOD);
}

by verden @ 2022-08-04 12:27:34

应该已经过了吧 这里的 topsort 求每个加操作的次数时,需要使用循环来加入度数为 0 的点,只加入超级源点 0 会导致有的点没有加入topsort就停止了。


by dbxxx @ 2022-09-04 10:12:44

@verden 请问一下除了超级源点以外,剩下的入度为 0 的点不是一定没被计算涉及到吗?为什么还要加入?


|