QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#211760#4620. If You Can't Beat Them, Join Them!yiyiyi#WA 683ms278760kbC++143.2kb2023-10-12 20:59:252023-10-12 20:59:26

Judging History

你现在查看的是最新测评结果

  • [2023-10-12 20:59:26]
  • 评测
  • 测评结果:WA
  • 用时:683ms
  • 内存:278760kb
  • [2023-10-12 20:59:25]
  • 提交

answer

#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define mp make_pair
#define rep(i,x,n) for(int i=x;i<=n;i++)
#define per(i,n,x) for(int i=n;i>=x;i--)
#define forE(i,x) for(int i=head[x];i;i=nxt[i])
#define pii pair<int,int>
#define fi first
#define se second
#define int long long
using namespace std;
const int INF=1e9+7;
const int mod=998244353;
const int maxn=4e6+5;
const int maxm=4e6+5;
inline int read()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9')
	{
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		x=x*10+(c-'0');
		c=getchar();
	}
	return x*f;
}
int k,n,m,s;
vector<int> e[maxn];
int cnt,ver[maxm],nxt[maxm],head[maxn];
inline void add(int x,int y)
{
    cnt++;
    ver[cnt]=y;
    nxt[cnt]=head[x];
    head[x]=cnt;
}
int dfn[maxn],low[maxn],num,st[maxn],top,tot,c[maxn];
vector<int> scc[maxn];
bool vis[maxn];
inline void tarjan(int x)//有向图强连通分量 
{
	dfn[x]=low[x]=++num;
	st[++top]=x,vis[x]=1;
	for(int i=head[x];i;i=nxt[i])
	{
		if(!dfn[ver[i]])
		{
			tarjan(ver[i]);
			low[x]=min(low[x],low[ver[i]]);
		}
		else if(vis[ver[i]]) low[x]=min(low[x],dfn[ver[i]]);
	}
	if(dfn[x]==low[x])
	{
		tot++;
		while(st[top+1]!=x)
		{
			c[st[top]]=tot,vis[st[top]]=0,scc[tot].push_back(st[top]);
			top--;
		}
	}
}

int sg[maxn],step[maxn];
int po[maxn];
pii b[maxn];
inline void init()
{
    cnt=num=top=tot=0;
    rep(i,0,n) head[i]=dfn[i]=low[i]=vis[i]=st[i]=c[i]=0,scc[i].clear(),e[i].clear();
    rep(i,0,n) sg[i]=step[i]=0;
}
inline void solve()
{
    int k=read();
    rep(i,1,k)
    {
        init();
        n=read(),m=read(),s=read();
        rep(j,1,m) {int x=read(),y=read();add(x,y);}
        rep(j,1,n) if(!dfn[j]) tarjan(j);
        rep(x,1,n)//缩点后变成DAG,而scc编号从大到小遍历就是拓扑序。
        {
            for(int j=head[x];j;j=nxt[j])
            {
                int y=ver[j];
                if(c[x]==c[y]) continue;
                e[c[x]].push_back(c[y]);
            }
        }
        rep(j,1,tot)
        {
            if(((int)scc[j].size()) > 1) {sg[j] = -1;step[j]=INF;continue;}
            if((int)e[j].size() == 0) {sg[j] = 0;step[j]=0;continue;}
            
            int f0=0,f1=0;
            for(auto y : e[j]) 
                if(sg[y] == 0) f0++;
                else if(sg[y] == -1) f1++;
            if(f0) sg[j]=1;
            else sg[j]=0;
            if(sg[j]==0&&f1) sg[j]=-1; 
            
            if(sg[j]==-1) step[j]=INF;
            else if(sg[j]==0)
            {
                for(auto y:e[j]) step[j]=max(step[j],step[y]);
                step[j]++; 
            }
            else
            {
                step[j]=INF;
                for(auto y:e[j]) if(sg[y]==0) step[j]=min(step[j],step[y]);
                step[j]++;
            }
        }
        b[i]=mp(step[c[s]],sg[c[s]]);
    }
    sort(b+1,b+k+1);
    int ans=0;
    rep(i,1,k)
    {
        if(b[i].second==0) continue;
        if(b[i].first>20000000) break;
        ans+=po[k-i];
        ans%=mod;
    }
    printf("%lld\n",ans);
}

signed main()
{
    po[0]=1;
    rep(i,1,2000000) po[i]=po[i-1]*2%mod;
    int T=read();
    while(T--)
    {
        solve();
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 683ms
memory: 278760kb

input:

5
1000
100 200 35
1 2
1 12
1 14
1 15
1 55
1 100
2 3
2 5
2 11
2 23
2 39
2 60
2 79
2 18
3 4
3 7
3 16
3 18
3 31
3 44
3 20
4 6
4 10
4 63
5 8
5 49
5 88
5 22
5 52
6 25
6 89
6 29
6 17
7 17
7 27
7 85
8 9
8 20
8 54
8 42
8 94
9 13
9 80
9 27
10 27
10 47
10 70
10 81
10 74
10 60
11 19
11 84
11 63
12 21
12 50
12 ...

output:

325998728
576
200
504
776469527

result:

wrong answer 2nd lines differ - expected: '792', found: '576'