这个题要知道一个定理。
给定m个数,a1,a2,a3,.....am,至少存在整数k,l,(1<=k<l<=m)使得ak+....+al是m的倍数。
构造前缀和:
s1=a1;
s2=a1+a2;
s3=a1+a2+a3;
...
sm=a1+a2+...+am;
(1)如果有一个sn是m的倍数,则定理得证。
(2) 如果在上面没有一个是m的倍数。令rh=Sh%m
其中,h=1,2,.....m,则所有rh均小于m,根据鸽巢定理可知至少存在一对rk,rh,满足rk==rh
即 Sk ≡ Sh % m
不过我写的G++TLE,C++AC
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
struct node{
int r,h;
}p[maxn];
bool cmp(const node& a,const node& b){
if(a.r==b.r) return a.h<b.h;
return a.r<b.r;
}
int main(){
int c,n;
while(scanf("%d%d",&c,&n)!=EOF&&(c||n)){
long long sum=0;
int a;
int k=-1;
for(int i=1;i<=n;i++){
scanf("%d",&a);
sum+=a;
p[i].r=sum%c;
p[i].h=i;
if(k==-1&&p[i].r==0) k=i;
}
int l,r;
if(k==-1){
sort(p+1,p+1+n,cmp);
for(int i=1;i<n;i++){
if(p[i].r==p[i+1].r){
l=p[i].h+1;
r=p[i+1].h;
k=l;
break;
}
}
}else{
l=1;r=k;
}
if(k==-1){
printf("no sweets\n");
}else{
for(int i=l;i<=r;i++){
if(i!=l) printf(" ");
printf("%d",i);
}
puts("");
}
}
return 0;
}