Codeforces 1270G Subset with Zero Sum

Codeforces 1270G Subset with Zero Sum

https://codeforces.com/contest/1270/problem/G

长度为 (n) 的正整数序列 (a_1,a_2,cdots,a_n) , 满足

[i - n le a_i le i - 1 ]

请找出一个非空子序列满足和为 (0) .

可以证明总是存在合法方案.

(T) 组数据.

(1 le T le 10^6)

(1 le n le 10^6, sum n le 10^6)

Tutorial

将不等式变形

[1 le i -a_i le n ]

可以建立一张 (n) 个点的有向图,从 (i)(i-a_i) 连边.

那么图中一定存在一个有向环,找到任意一个这样的环,设其中的点为 (u_1,u_2,cdots,u_k) ,则有

[u_1-a_{u_1}=u_2 \ u_2-a_{u_2}=u_3 \ cdots \ u_k-a_{u_k}=u_1 ]

所以可以得到 (a_{u_1}+a_{u_2}+cdots+a_{u_k}=0) .

复杂度 (O(n))

Code

#include <cassert>
#include <cstdio>
#include <iostream>
#include <vector>
#define debug(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
inline char nc()
{
//	return getchar();
	static char buf[100000],*l=buf,*r=buf;
	return l==r&&(r=(l=buf)+fread(buf,1,100000,stdin),l==r)?EOF:*l++;
}
template<class T> void read(T &x)
{
	x=0; int f=1,ch=nc();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=nc();}
	while(ch>='0'&&ch<='9'){x=x*10-'0'+ch;ch=nc();}
	x*=f;
}
typedef long long ll;
const int maxn=1e6+50;
int n;
int T;
int a[maxn];
bool vis[maxn];
vector<int> R;
vector<int> an;
void dfs(int u)
{
	if(vis[u]) return; vis[u]=1;
	R.push_back(u);
	dfs(u-a[u]);
}
int main()
{
	read(T);
	for(int kase=1;kase<=T;++kase)
	{
		read(n);
		for(int i=1;i<=n;++i)
		{
			read(a[i]);
		}
		dfs(1);
		ll sum=0;
		for(int i=R.size()-1;~i;--i)
		{
			sum+=a[R[i]]; an.push_back(R[i]);
			if(sum==0) break;
		}
		printf("%d
",(int)an.size());
		for(int i=0;i<an.size();++i)
		{
			if(i) printf(" ");
			printf("%d",an[i]);
		}
		printf("
");
		R.clear();
		an.clear();
		for(int i=1;i<=n;++i) vis[i]=0;
	}
	return 0;
}
原文地址:https://www.cnblogs.com/ljzalc1022/p/12989510.html