AtCoder Beginner Contest 387

可算找到了tarjan板子

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define yes cout << "Yes" << endl
#define no cout << "No" << endl
#define pii pair<int,int>
#define ll long long
#define pb push_back
#define ft first
#define se second
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define int long long

int n,m;
const int p=998244353;
const int N=3000;
vector<int> G[N];
int dfn[N],low[N],stk[N],instk[N],scc[N];int cnt_scc;int tot=0;int tp=0;
vector<int>G1[N],E1[N];
int f[N][N],g[N][N];
void tarjan(int u)
{
    dfn[u]=low[u]=++tot;
    instk[u]=1,stk[++tp]=u;
    for(auto v:G[u])
    {
        if(dfn[v]==0)
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instk[v])
        {
            low[u]=min(low[u],dfn[v]);
        }
    }
    if(dfn[u]==low[u])
    {
        int now;
        cnt_scc++;
        do{
            now=stk[tp--];
            instk[now]=0;
            scc[now]=cnt_scc;
        }while(now!=u);
    }
}


int ind[N];bool nood[N];
vector<int> topo;
void toposort(){
    stack<int> s;topo.pb(0);
    for(int i=1;i<=cnt_scc;i++){
        if(!ind[i]){s.push(i);
            // for(int j=1;j<=m;j++)f[i][j]=1;
            // for(int j=1;j<=m;j++)g[i][j]=g[i][j-1]+f[i][j];
        }
    }
    while(!s.empty()){
        int t=s.top();s.pop();
        topo.pb(t);
        for(auto v:G1[t]){
            if(--ind[v]==0)s.push(v);
        }
    }

}
void solve(){
cin>>n>>m;
for(int i=1;i<=n;i++){
    int _;cin>>_;G[i].pb(_);nood[i]=1;
}
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);


for(int i=1;i<=n;i++){
    int u=i;u=scc[i];
    for(auto v:G[i]){
        v=scc[v];
        if(u!=v){G1[u].pb(v);nood[u]=0;
            E1[v].pb(u);ind[v]++;}
    }
}

toposort();


for(int ii=1;ii<=cnt_scc;ii++){
    int i=topo[ii];
    for(int j=1;j<=m;j++){
        f[i][j]=1;
    }
   for(auto v:E1[i]){
    for(int j=1;j<=m;j++){
        f[i][j]=(f[i][j]*g[v][j])%p;
    }
   }
   for(int j=1;j<=m;j++)g[i][j]=(g[i][j-1]+f[i][j])%p;
  // cout<<"geti"<<i<<"*";for(int j=1;j<=m;j++)cout<<f[i][j]<<" ";cout<<'\n';
}
int ans=1;
for(int i=1;i<=cnt_scc;i++){
if(nood[i])ans=(ans*g[i][m])%p;
}
cout<<ans<<'\n';
}
signed main(){
    std::ios::sync_with_stdio(false);
    int T=1;
    while(T--){
        solve();
    }
}
posted @ 2025-12-17 09:35  arin876  阅读(3)  评论(0)    收藏  举报