QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#211760 | #4620. If You Can't Beat Them, Join Them! | yiyiyi# | WA | 683ms | 278760kb | C++14 | 3.2kb | 2023-10-12 20:59:25 | 2023-10-12 20:59:26 |
Judging History
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'