1103 N的倍数 (抽屉原理)
Posted 7391_KID
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1103 N的倍数 (抽屉原理)相关的知识,希望对你有一定的参考价值。
题意:一个长度为N的数组A,从A中选出若干个数,使得这些数的和是N的倍数。
例如:N = 8,数组A包括:2 5 6 3 18 7 11 19,可以选2 6,因为2 + 6 = 8,是8的倍数。(2 <= N <= 50000,0 < A[i] <= 10^9)
分析:在modN意义下求A的前缀和,若有为0的前缀和,前k个即为所求;若没有,有抽屉原理,必然存在两个值相等的前缀和,两者相减即为所求.
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 const int maxn=50005; 5 int n,a[maxn],Hash[maxn],l,r; 6 class Tree{ 7 private: 8 int c[maxn],n; 9 public: 10 Tree(int _n){this->n=_n;memset(c,0,sizeof(c));} 11 void add(int k,int num){ 12 while(k<=this->n){ 13 c[k]=(c[k]+num)%n; 14 k+=k&-k; 15 } 16 } 17 int read(int k){ 18 int sum=0; 19 while(k){ 20 sum=(sum+c[k])%n; 21 k-=k&-k; 22 } 23 return sum; 24 } 25 }; 26 int main(){ 27 cin>>n; 28 Tree t(n); 29 memset(Hash,0,sizeof(Hash)); 30 for(int i=1;i<=n;i++){ 31 cin>>a[i]; 32 t.add(i,a[i]%n); 33 } 34 for(int i=1;i<=n;i++){ 35 int k=t.read(i); 36 if(k==0){ 37 l=1;r=i;break; 38 } 39 else if(Hash[k]){ 40 l=Hash[k]+1;r=i;break; 41 }else{ 42 Hash[k]=i; 43 } 44 } 45 cout<<r-l+1<<endl; 46 for(int i=l;i<=r;i++){ 47 cout<<a[i]<<endl; 48 } 49 return 0; 50 }
以上是关于1103 N的倍数 (抽屉原理)的主要内容,如果未能解决你的问题,请参考以下文章