AtCoder Beginner Contest 105 D Candy Distribution 题解

AtCoder Beginner Contest 105 D Candy Distribution

Problem Statement

There are N boxes arranged in a row from left to right. The i-th box from the left contains *A**i* candies.

You will take out the candies from some consecutive boxes and distribute them evenly to M children.

Such being the case, find the number of the pairs (l,r) that satisfy the following:

  • l and r are both integers and satisfy 1≤lrN.
  • Al+Al+1+…+*A**r* is a multiple of M.

Constraints

  • All values in input are integers.
  • 1≤N≤105
  • 2≤M≤109
  • 1≤*A**i*≤109

Input

Input is given from Standard Input in the following format:

N M
A1 A2 … AN

Output

Print the number of the pairs (l,r) that satisfy the conditions.

Note that the number may not fit into a 32-bit integer type.

Sample Input 1

3 2
4 1 5

Sample Output 1

3 

The sum Al+Al+1+…+*A**r* for each pair (l,r) is as follows:

  • Sum for (1,1): 4
  • Sum for (1,2): 5
  • Sum for (1,3): 10
  • Sum for (2,2): 1
  • Sum for (2,3): 6
  • Sum for (3,3): 5

Among these, three are multiples of 2.

Sample Input 2

13 17
29 7 5 7 9 51 7 13 8 55 42 9 81

Sample Output 2

6

Sample Input 3

10 400000000
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000

Sample Output 3

25

题解

题意

N个盒子,每个盒子内的糖果数有Ai个,问区间(l,r)范围内,糖果数总和为M倍数的区间有几个?

思路

首先,按照Ai%M的数目进行统计,得到在Ai%M的组数。然后可以选取区间,对于%M为0的组数,直接添加组数。对于%M为其他值的组数,加上组数X(组数-1)/2。最终得到数目。

注意,由于M非常大而且有很多空值,所以数组方法不现实,最开始在这里坑了一次,后来转向map才写明白,耽误了一部分时间。

代码

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
 
#define REP(i,n) for(int i=0;i<(n);i++)
 
const int MAXN = 1e5+10;
 
ll A[MAXN];
ll sum[MAXN];
map<int,int>m1;
 
int main(){
    ll N,M;
    scanf("%d %d",&N,&M);
    for(int i=0;i<N;i++){
        scanf("%lld",&A[i]);
    }
    memset(sum,0,sizeof(sum));
    sum[0] = A[0];
    m1.insert(make_pair(A[0]%M,1));
    for(int i=1;i<N;i++){
        sum[i] = sum[i-1]+A[i];
        int c = sum[i]%M;
        map<int,int>::iterator iter = m1.find(c);
        ll a=0;
        ll b=0;
        if(iter!=m1.end()){
            a = iter->first;
            b = iter->second;
            m1.erase(iter);
            m1.insert(make_pair(a,b+1));
        }else{
            a = c;
            m1.insert(make_pair(a,1));
        }
    }
    ll ans = 0;
    map<int,int>::iterator iter;
    for(iter=m1.begin();iter!=m1.end();iter++){
        ll a= iter->first;
        ll b= iter->second;
        if(a==0)    ans+=b;
        ans += b*(b-1)/2;
    }
    printf("%lld\n",ans);
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/caomingpei/p/9468687.html
今日推荐