【题解】
先预处理出模N意义下的前缀和sum[i]。
1.如果sum[i]=0,那么1~i的数之和就是N的倍数
2.sum[i]%N总共有0~N-1这N种情况;根据1,如果sum[i]为0则必定有解;如果不存在sum[i]=0,那么根据抽屉原理,有N个前缀和,N-1种情况,那么一定存在sum[i]=sum[j],那么i+1~j的数之和就是N的倍数
由上可知,一定存在一种方案满足取出连续的一些数使得这些数的和是N的倍数

1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int maxn=50010; 5 int n,a[maxn],sum[maxn],last[maxn]; 6 void read(int &k){ 7 k=0; int f=1; char c=getchar(); 8 while (c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 9 while ('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 10 k*=f; 11 } 12 int main(){ 13 read(n); 14 for (int i=1;i<=n;i++) read(a[i]),sum[i]=(sum[i-1]+a[i])%n; 15 for (int i=1;i<=n;i++){ 16 if (sum[i]==0){ 17 printf("%d ",i); 18 for (int j=1;j<=i;j++) printf("%d ",a[j]); 19 return 0; 20 } 21 else if (last[sum[i]]){ 22 printf("%d ",i-last[sum[i]]); 23 for (int j=last[sum[i]]+1;j<=i;j++) printf("%d ",a[j]); 24 return 0; 25 } 26 last[sum[i]]=i; 27 } 28 }