正题
题目链接:https://jzoj.net/senior/#main/show/3783
题目大意
nnn个数,求这个序列中一个非空子集的和是nnn的倍数。
解题思路
可以知道一定有一种解法是一段连续的序列。
证明:设sxs_xsx表示(∑i=1xai)%n(\sum_{i=1}^xa_i)\%n(∑i=1xai)%n,那么我们要找到一个sl=srs_l=s_rsl=sr。
若有si=0s_i=0si=0,那么显然有答案
若没有sis_isi为0,那么在这nnn个数中有n−1n-1n−1个可能的取值,那么就必定有一个sl=srs_l=s_rsl=sr。
证毕
然后O(n)O(n)O(n)搞sis_isi就好了。
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100010;
int T,n,a[N],sum,l,r,v[N*2];
int main()
{//freopen("checkin.in","r",stdin);//freopen("checkin.out","w",stdout);scanf("%d",&T);while(T--){scanf("%d",&n);memset(v,0,sizeof(v));sum=0;l=-1;r=-1;for(int i=1;i<=n;i++){scanf("%d",&a[i]);sum=(sum+a[i])%n;if(!sum){l=0;r=i;}if(v[sum+n]){l=v[sum+n];r=i;} v[sum+n]=i;}if(l==-1){printf("-1\n");continue;}printf("%d\n",r-l);for(int i=l+1;i<=r;i++)printf("%d ",a[i]);putchar('\n');}
}