Codeforces - Subset with Zero Sum

You are given n integers a1,a2,…,an, such that for each 1≤i≤n holds i−n≤ai≤i−1.

Find some nonempty subset of these integers, whose sum is equal to 0. It can be shown that such a subset exists under given constraints. If there are several possible subsets with zero-sum, you can find any of them.

Input
Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤106). The description of the test cases follows.

The first line of each test case contains a single integer n (1≤n≤106).

The second line of each test case contains n integers a1,a2,…,an (i−n≤ai≤i−1).

It is guaranteed that the sum of n over all test cases does not exceed 106.

Output
For each test case, output two lines.

In the first line, output s (1≤s≤n) — the number of elements in your subset.

In the second line, output s integers i1,i2,…,is (1≤ik≤n). All integers have to be pairwise different, and ai1+ai2+⋯+ais has to be equal to 0. If there are several possible subsets with zero-sum, you can find any of them.

Example
inputCopy
2
5
0 1 2 3 4
4
-3 1 1 1
outputCopy
1
1
4
1 4 3 2
Note
In the first example, we get sum is a1=0.

In the second example, we get sum is a1+a4+a3+a2=0.


看了题解才会的憨憨。(感觉完全想不到)

由 i−n≤ai≤i−1. 我们可以得到 i-ai 是在1 到 n之间的。然后我们让 i 连向 i-a[i] ,这样,如果我们能找到一个环,那么这个环的元素之和为0,不难证明,所以找环即可。


AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,a[N],T,pre[N],vis[N],flag;
int head[N],nex[N],to[N],tot;
inline void add(int a,int b){to[++tot]=b; nex[tot]=head[a]; head[a]=tot;}
void dfs(int x){
    if(flag)    return ;    vis[x]=1;
    for(int i=head[x];i;i=nex[i]){
        if(vis[to[i]])  return void(flag=to[i]);    dfs(to[i]);
    }
}
inline void solve(){
    scanf("%d",&n); tot=flag=0; for(int i=1;i<=n;i++) head[i]=vis[i]=0;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),add(i,i-a[i]);
    for(int i=1;i<=n&&!flag;i++)    if(!vis[i]) dfs(i);
    vector<int> res; res.push_back(flag); int t=flag-a[flag];
    while(t!=flag){res.push_back(t); t=t-a[t];}
    printf("%d\n",res.size());
    for(int i=0;i<res.size();i++)   printf("%d ",res[i]);puts("");
}
int main(){
    cin>>T; for(int i=1;i<=T;i++)   solve();
    return 0;
}
发布了416 篇原创文章 · 获赞 228 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/103792311