题意
给定 N 个正整数 a1 ,a2 ,…, an 。 要求从其中选出若干数字, 使得这些数字的和 mod N = 0 (对于每个下标最多只能选择一次)。
1 ≤ N ≤ 100000,1 ≤ ai ≤ 10^9
思路
原本以为是01背包,1e5的数据范围可以用bitset优化,但只能求出是否有解,没法求解;
若对原数组求取模后的前缀和 sum ,则对于sum数组中的每个数,均位于[0,n - 1],共 n 种取值,而 sum[0 ~ n] 有n + 1 个数,根据抽屉原理,必定至少存在两个取值相同的数,设为l ,r,也就是说,sum[l] = sum[r],区间[l + 1,r]的和为零,也就是答案;
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[100010],sum[100010];
int vis[100010];
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
memset(vis,-1,sizeof(vis));
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=(sum[i-1]+a[i])%n;
}
int x,y;
for(int i=0;i<=n;i++){
if(vis[sum[i]]==-1) vis[sum[i]]=i;
else{ x=vis[sum[i]]+1; y=i; break;}
}
cout<<y-x+1<<"\n";
for(int i=x;i<=y;i++) cout<<i<<" ";
return 0;
}