算法分析
抽屉原理 + 前缀和 ??!!
首先根据抽屉原理,我们可以保证本题必定有解,因为取 个数
要么会出现
,要么就会出现前缀
,所以根据这个原理这题目就很简单了。
对这些数字做前缀和,倘若出现 了,那么就直接输出前缀的方案就可以了
倘若出现了,那么就把
和
之间的数字给输出就可以了
和
只需要开一个
数组维护一下
曾经出现的值就可以了
详情见代码
AC Code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
map<ll,ll>mp;
ll a[N],s[N],id[N];
int main()
{
int n;
cin >> n;
for(int i = 1;i <= n;i ++) scanf("%lld",&a[i]);
for(int i = 0;i < N;i ++) id[i] = -1;
int st,ed;
for(int i = 0;i < n;i ++)
{
s[i + 1] = (s[i] + a[i + 1]) % n;
if(s[i + 1] == 0)
{
printf("%d\n",i + 1);
for(int j = 1;j <= i + 1;j ++)
printf("%d ",j);
return 0;
}
//cout << s[i + 1] <<" ";
if(id[s[i + 1]] != -1)
{
st = id[s[i + 1]];
ed = i + 1;
break;
}
id[s[i + 1]] = i + 1;
}
printf("%d\n",ed - st);
for(int i = st + 1;i <= ed;i ++)
printf("%d ",i);
return 0;
}