QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#638424#8212. Football in OsijekDjangle162857#WA 4ms38736kbC++232.9kb2024-10-13 15:54:132024-10-13 15:54:14

Judging History

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

  • [2024-10-13 15:54:14]
  • 评测
  • 测评结果:WA
  • 用时:4ms
  • 内存:38736kb
  • [2024-10-13 15:54:13]
  • 提交

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;
}

详细

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'