题面

Subset with Zero Sum

给出 n n n 个整数 a 1 , a 2 , ⋯   , a n a _ 1 , a _ 2 , \cdots , a _ n a1,a2,,an,对于所有的 1 ≤ i ≤ n 1 \le i \le n 1in 满足 i − n ≤ a i ≤ i − 1 i - n \le a _ i \le i - 1 inaii1

找出这些整数的非空子集,满足元素和为 0 0 0。根据题目,一定存在子集满足条件。如果有多个满足条件的子集,输出任意一个。

输入

每个测试包含多个测试用例。第一行是测试用例的数量 t t t 1 ≤ t ≤ 10 6 1 \le t \le 10 ^ 6 1t106)。每个用例的输入格式如下。

每个用例的第一行包括一个单独的整数 n n n 1 ≤ n ≤ 10 6 1 \le n \le 10 ^ 6 1n106)。

第二行包括 n n n 个整数 a 1 , a 2 , ⋯   , a n a _ 1 , a _ 2 , \cdots , a _ n a1,a2,,an i − n ≤ a i ≤ i − 1 i - n \le a _ i \le i - 1 inaii1)。

保证所有用例的 n n n 的总和不超过 10 6 10 ^ 6 106

输出

对于每个测试用例,输出两行。

在第一行,输出 s s s 1 ≤ s ≤ n 1 \le s \le n 1sn)表示子集中的元素个数。

在第二行,输出 s s s 个整数 i 1 , i 2 , ⋯   , i s i _ 1 , i _ 2 , \cdots , i _ s i1,i2,,is 1 ≤ i k ≤ n 1 \le i _ k \le n 1ikn)。所有整数不同,且 a i 1 + a i 2 + ⋯ + a i s = 0 a _ {i _ 1} + a _ {i _ 2} + \cdots + a _ {i _ s} = 0 ai1+ai2++ais=0

思路

tag \text{tag} taggraphs math

对“一定存在子集满足条件”的证明

i − n ≤ a i ≤ i − 1 i - n \le a _ i \le i - 1 inaii1 进行移项变形,得 1 ≤ i − a i ≤ n 1 \le i - a _ i \le n 1iain。又 i i i 的取值为 1 ≤ i ≤ n 1 \le i \le n 1in,且 a i a _ i ai 的下标取值也为 1 1 1 n n n,故若将 1 1 1 n n n 设为点, 1 ≤ i ≤ n 1 \le i \le n 1in 的所有 i i i i − a i i - a _ i iai 连有向边,则得到一个 n n n 个点, n n n 条边的有向图,每个点出度为 1 1 1

这时容易发现,因为点数与边数相等,故图不可能为树,即图中存在一个环,那么由于收尾相连,所以环上点的编号和会与环上点的子节点的编号和相等,即 ∑ i = ∑ ( i − a i ) \sum i = \sum (i - a _ i) i=(iai)。移项,得 ∑ a i = 0 \sum a _ i = 0 ai=0。于是,环上点的编号集合即为答案集合。

图上找环的时间复杂度为 O ( n ) O(n) O(n)

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1e6+5;
int a[maxn];
bool vis[maxn];
int cnt[maxn];
int n;
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		vis[i]=0;
	}
	int now=1,all=1;
	while(!vis[now]){
		vis[now]=1,cnt[now]=all;
		now-=a[now],all++;
	}
	cout<<all-cnt[now]<<"\n";
	int x=now;
	do{
		cout<<x<<" ";
		x=x-a[x];
	}while(x!=now);
	cout<<"\n";
}
signed main(){
	ios::sync_with_stdio(0);
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐