QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#638424 | #8212. Football in Osijek | Djangle162857# | WA | 4ms | 38736kb | C++23 | 2.9kb | 2024-10-13 15:54:13 | 2024-10-13 15:54:14 |
Judging History
answer
#define _CRT_SECURE_NO_WARNINGS
#include<queue>
#include<vector>
#include<bitset>
#include<iomanip>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=500010;
const int inf=1000000000;
int n,cnt,v[N],ans[N],s[N],iscir[N];
struct Node{
int maxilen,cir,x;
//maxilen 最长链 cir 环长 x 代表节点 并查集里的父亲
Node(){}
Node(int _maxilen,int _cir,int _x):maxilen(_maxilen),cir(_cir),x(_x){}
inline bool operator<(const Node that){
return maxilen+cir<that.maxilen+that.cir;
}
}a[N];
struct DSU{
int fa[N],siz[N];
inline void init(int x){for(int i=1;i<=x;i++)fa[i]=i,siz[i]=1;}
inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
inline int merge(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx==fy)return 0;
if(siz[fx]<siz[fy])swap(fx,fy);
fa[fy]=fx;
return 1;
}
}t;
struct Graph{
int vis[N];
vector<int>e[N],e2[N],stk,poscir;
inline void lnk(int x,int y)
{
e[x].push_back(y);
e2[y].push_back(x);
}
inline void dfs2(int x,int id,int dep) // 用反图 找最长链子
{
a[id].maxilen=max(a[id].maxilen,dep);
for(auto y:e2[x])
{
if(iscir[y])continue;
dfs2(y,id,dep+1);
}
}
inline void dfs(int x,int id) //id 这个基环树的编号
{
vis[x]=1;
stk.push_back(x);
for(auto y:e[x])
{
if(vis[y])
{
int len=0,lim=stk.size();
for(int i=lim-1;i>=0;i--)
{
int pos=stk[i];
poscir.push_back(pos);
len++;
iscir[pos]=1;
if(pos==y)break;
}
a[id].cir=len;
for(auto z:poscir)
dfs2(z,id,0);
return;
}
dfs(y,id);
}
}
}e;
int main()
{
scanf("%d",&n);
t.init(n);
for(int i=1,pos;i<=n;i++)
scanf("%d",&pos),e.lnk(i,pos),t.merge(i,pos);
for(int i=1;i<=n;i++)
{
int pos=t.find(i);
if(v[pos])continue;
v[pos]=1;
a[++cnt]=Node(0,0,pos);
}
for(int i=1;i<=cnt;i++)
{
while(e.stk.size())
e.stk.pop_back();
while(e.poscir.size())
e.poscir.pop_back();
e.dfs(a[i].x,i);
}
//for(int i=1;i<=cnt;i++)
// cout<<a[i].cir<<" "<<a[i].maxilen<<" "<<a[i].x<<endl;
for(int i=1;i<=n;i++)
ans[i]=inf;
sort(a+1,a+1+cnt);
for(int i=1;i<=cnt;i++)
s[a[i].cir]++,s[a[i].maxilen+a[i].cir+1]--;
for(int i=1;i<=n;i++)
{
s[i]+=s[i-1];
if(s[i])ans[i]=0;
}
for(int i=1;i<=n;i++)
s[i]=0;
for(int i=1;i<=cnt;i++)
{
s[1]+=1;
s[a[i].cir+a[i].maxilen+1]--;
}
for(int i=1;i<=n;i++)
{
s[i]+=s[i-1];
if(s[i])ans[i]=min(ans[i],1);
}
//for(int i=1;i<=n;i++)
// printf("%d ",ans[i]);
reverse(a+1,a+1+cnt);
int pt=a[1].cir+a[1].maxilen,sum=a[1].cir+a[1].maxilen;
for(int i=2;i<=cnt;i++)
{
sum+=a[i].maxilen+a[i].cir;
while(pt+1<=n&&pt+1<=sum)
pt++,ans[pt]=min(ans[pt],i-1);
if(pt==n)break;
}
for(int i=1;i<=n;i++)
printf("%d ",ans[i]);
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 4ms
memory: 38736kb
input:
5 2 3 1 3 5
output:
0 1 0 0 1
result:
ok 5 number(s): "0 1 0 0 1"
Test #2:
score: 0
Accepted
time: 0ms
memory: 38608kb
input:
1 1
output:
0
result:
ok 1 number(s): "0"
Test #3:
score: 0
Accepted
time: 0ms
memory: 38680kb
input:
2 2 2
output:
0 0
result:
ok 2 number(s): "0 0"
Test #4:
score: -100
Wrong Answer
time: 0ms
memory: 38664kb
input:
10 4 7 2 8 4 3 4 9 7 3
output:
1 1 1 0 0 0 0 1000000000 1000000000 1000000000
result:
wrong answer 8th numbers differ - expected: '1', found: '1000000000'