「UVA11237」Halloween treats
题意
有 \(c\) 个孩子,\(n\) 个邻居,给出每个邻居会给孩子们的糖果数 \(a_i\)。
求出几个邻居的编号,使得他们给的糖果数总和能让孩子们平分。
分析
题面里给了一个很重要的条件 \(c\le n\)。
设 \(s_i=\sum\limits_{i=1}^{n}a_i\),由鸽巢原理,当 \(c<n\) 时,显然有 \(i<j\) 使得 \(s_i\equiv s_j \pmod c\),那么 \(a_{i+1}\sim a_{j}\) 便是一组答案。
当 \(c=n\) 时,必定有 \(s_i\bmod c=0\),则 \(a_1\sim a_i\) 便是一组答案。
预处理出前缀和,先特判 \(c=n\) 的情况,然后设一个数组记录上一个 \(s_i\bmod c\) 的位置,若当前值已经出现过,直接输出即可。
时间复杂度 \(O(n)\),可过,注意多测。
Code
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
#define dbg(x) cout<<#x<<": "<<x<<"\n"
inline ll read(){ll x=0,f=1;char c=getchar();while(c<48||c>57){if(c==45)f=0;c=getchar();}while(c>47&&c<58)x=(x<<3)+(x<<1)+(c^48),c=getchar();return f?x:-x;}
const ll mod=1e9+7,maxn=1e5+5,maxt=505;
ll n,m,a[maxn],b[maxn],cnt[maxn];
inline void solve(){
if(n==0)return;
for(ll i=1;i<=m;++i){
a[i]=read();
b[i]=(b[i-1]+a[i])%n;
}
memset(cnt,-1,sizeof(cnt));
for(ll i=1;i<=m;++i){
if(cnt[b[i]]!=-1){
for(ll j=cnt[b[i]]+1;j<=i;++j)printf("%lld ",j);
puts("");
return;
}
else cnt[b[i]]=i;
}
}
signed main(){
while((n=read())&&(m=read())){
solve();
}
return 0;
}

浙公网安备 33010602011771号