多多路上从左到右有N棵树(编号1~N),其中第i个颗树有和谐值Ai。
多多鸡认为,如果一段连续的树,它们的和谐值之和可以被M整除,那么这个区间整体看起来就是和谐的。现在多多鸡想请你帮忙计算一下,满足和谐条件的区间的数量。
第一行,有2个整数N和M,表示树的数量以及计算和谐值的参数。
( 1 <= N <= 100,000, 1 <= M <= 100 )
第二行,有N个整数Ai, 分别表示第i个颗树的和谐值。
( 0 <= Ai <= 1,000,000,000 )
共1行,每行1个整数,表示满足整体是和谐的区间的数量。
5 2 1 2 3 4 5
6
长度为1: [2], [4]
长度为2: 无
长度为3: [1,2,3], [3,4,5]
长度为4: [1,2,3,4], [2,3,4,5]
长度为5: 无
共6个区间的和谐值之和可以被2整除。
对于50%的数据,有N<=1,000对于100%的数据,有N<=100,000
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] params = br.readLine().split(" ");
int n = Integer.parseInt(params[0]);
int m = Integer.parseInt(params[1]);
int[] map = new int[m]; // 除以m的余数为0~m-1
params = br.readLine().split(" ");
int[] A = new int[n];
map[0] = 1;
long culSum = 0L;
long count = 0L;
for(int i = 0; i < n; i++) {
A[i] = Integer.parseInt(params[i]);
culSum += A[i];
int remain = (int)(culSum % m);
count += map[remain];
map[remain] ++;
}
System.out.println(count);
}
} #include <iostream>
#include <cstring>
using namespace std;
int main(){
int n, m;
cin>>n>>m;
int arr[n];
for (int i = 0; i < n; ++i){
cin>>arr[i];
}
int map[m];//下标表示前缀和 % m后的值,map[i]表示取余后值为i的个数;
memset(map, 0, sizeof(map));
map[0] = 1;//需要设置这个初始值,看下面代码就懂了
long sum = 0;
long ans = 0;
for (int i = 0; i < n; ++i){
sum += arr[i];
int index = sum % m;
ans += map[index]++;
}
cout<<ans<<endl;
return 0;
} import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int M = sc.nextInt();
int[] ais = new int[N];
int[] sums = new int[N+1];
for(int i=0;i<N;i++){
ais[i] = sc.nextInt();
sums[i+1] = (sums[i]+ais[i])%M;
}
Map<Integer,Long> map = new HashMap<>();
for(int i=0;i<=N;i++){
int local = sums[i]%M;
map.put(local,map.getOrDefault(local,0l)+1l);
}
long res = 0;
for(long val:map.values()){
res += val*(val-1)/2;
}
System.out.println(res);
}
} #include <bits/stdc++.h>
typedef long long ll;
using namespace std;
ll n,m,a,sum=0,v[1005],ans;
int main()
{
ios::sync_with_stdio(0),cin.tie(0);
int i,j;
cin>>n>>m;
v[0]=1;/**< 用v数组统计每个位置前缀和余数的个数,相同余数的区间必然能被m整除 */
for(i=1;i<=n;i++)
{
cin>>a;
sum=(sum+a)%m;
v[sum]++;
}
for(i=0;i<m;i++)/**< 相同余数任选2个都可以和谐区间 */
ans+=v[i]*(v[i]-1)/2;
cout<<ans;
return 0;
} #include <iostream>
#include <vector>
using namespace std;
int main() {
long long n, m;
cin >> n >> m;
vector<long long> cnt(m, 0); //前缀和余数出现的次数
cnt[0] = 1; // 数值未加入前,前缀和为0,统计起点为0的情况
//前缀和sum[j] - sum[i]为区间[i, j]的总和
//所以统计前缀和余数相同的数出现的次数,任意选两个可以组成一个和谐区间
long long tree;
long long sum = 0;
for(int i = 0; i < n; i ++){
cin >> tree;
tree = tree % m;
sum = (sum + tree) % m;
cnt[sum] ++;
}
long long ans = 0;
for(int i = 0; i < m; i ++){
ans += cnt[i] * (cnt[i] - 1)/2;
}
cout << ans << endl;
return 0;
} private static int f(int[] arr,int mod){
int n = arr.length,count=0;
//c代表区间长度
for(int c=1;c<=n;c++){
//区间开始结束值以及区间和的大小
int end=0,start=0;
long sum=0;
while (end<c-1){
sum+=arr[end++];
}
//从左到右“滑动区间”并计算是否满足条件
while (end<n){
sum+=arr[end++];
if(sum%mod==0){
count++;
}
sum-=arr[start++];
}
}
return count;
} private static int f(int[] arr,int mod){
long[] prefix=new long[arr.length+1];
int k=1;
for(int i : arr){
prefix[k]=prefix[k-1]+i;
k++;
}
int n = arr.length,count=0;
for(int c=1;c<=n;c++){
int start=0;
int end = start+c-1;
if(end<n){
while(end<n){
if((prefix[end+1]-prefix[start])%mod==0){
count++;
}
start++;end++;
}
}else {
break;
}
}
return count;
} private static long f(int[] arr,int mod){
long[] prefix=new long[arr.length];
prefix[0]=arr[0];
Map<Long,Long> map = new HashMap<>();
map.put(prefix[0]%mod,1L);
for(int i=1;i<arr.length;i++){
prefix[i]=prefix[i-1]+arr[i];
map.put(prefix[i]%mod,map.getOrDefault(prefix[i]%mod,0L)+1);
}
return map.values().stream().mapToLong(n->n*(n-1)/2).sum()
+map.getOrDefault(0L,0L);
//需要加上单值区间直接可以mod到0的情况
} # 利用前缀和原理 n,m = list(map(int, input().strip().split(' '))) # 主要在意M就行,要能被M整除 ai=list(map(int,input().strip().split(' '))) # 每个数组的值 li={0:1} # li字典放所有的前缀和 除 m 得到的余数出现的次数,初始化我们需要 使出现 余数为 0 出现一次 sum=0 count = 0 # 用来统计 for i in ai: sum+= i # 前缀和 yu=sum%m # 求前缀和的除m的余数 if yu in li.keys(): # 如果 已有存在的key(余数)说明到他这里我们必有可以除断的。(可以理解为余数一样的那么中间这一段必定可以除断) # 然后我们需要看几个余数一样的来判断可以组合几个 count += li[yu] if yu not in li.keys(): # 将前缀和的余数存进字典 li[yu]=1 else: li[yu]+=1 print(count)
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int M = scanner.nextInt();
int[] A = new int[N];
for(int i = 0; i < N; i++){
A[i] = scanner.nextInt();
}
int count = 0;
int sum = 0;
Map<Integer, Integer> record = new HashMap<>();
//遍历数组nums之前,record提前放入 0:1 键值对,代表求第 0 项前缀和之前,前缀和 mod K 等于 0 这种情况出现了 1 次。
record.put(0,1);
for(int elem : A){
sum+=elem;//前缀和
int model = (sum % M + M) % M;//取余数
//getOrDefault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值0。
record.put(model, record.getOrDefault(model, 0)+1);
}
//values() 方法返回映射中所有 value 组成的 Set 视图
for(int n : record.values()){
count+=n*(n-1)/2;
}
//for(Map.Entry<Integer, Integer> entry : record.entrySet()){
// count+=entry.getValue()*(entry.getValue()-1)/2;
//}
System.out.println(count);
}
}
var firstline=readline().split(" ")
var listlen=parseInt(firstline[0])
var harmonum=parseInt(firstline[1])
var list=readline().split(" ")
var lista=list.map(item=>parseInt(item))
//存放0-i位置的数组和的余数
var leftnum=[]
var sumtmp=0
var ans=0
//存放某个余数的出现个数
var map=new Map([[0,0]])
for(var i=0;i<listlen;i++){
sumtmp+=lista[i]
if(sumtmp%harmonum==0){ans+=1}
if(!map.has(sumtmp%harmonum)){
map.set(sumtmp%harmonum,1)
}else{
ans+=map.get(sumtmp%harmonum)
map.set(sumtmp%harmonum,map.get(sumtmp%harmonum)+1)
}
}
console.log(ans) js版本n,m = list(map(int, input().strip().split(' '))) ai=list(map(int,input().strip().split(' '))) li={} sum=0 for i in ai: sum+=i yu=sum%m if yu not in li.keys(): li[yu]=1 else: li[yu]+=1 hh=0 for i,j in li.items(): if i==0: hh+=j nn=j*(j-1)//2 hh+=nn print(hh)
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
int n = in.nextInt() , m = in.nextInt();in.nextLine();
int[] cnt = new int[m];
cnt[0]++;
int preModSum = 0;
long res = 0;
for (int i = 0;i<n;i++){
preModSum = (preModSum + in.nextInt()) % m;
res+= cnt[preModSum];
cnt[preModSum]++;
}
System.out.print(res);
}
} from collections import defaultdict n, m = map(int, input().split()) lst = list(map(int, input().split())) preSum = [0]*(n+1) res = 0 dic = defaultdict(int) dic[0] = 1 for i in range(1, n+1): preSum[i] = preSum[i-1]+lst[i-1] mod = preSum[i]%m if mod in dic: res += dic[mod] dic[mod] += 1 print(res)
import java.util.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static long countHarmonySubarrays(long[] A, int M) {
long count = 0;
long[] P = new long[A.length + 1];
Map<Long, Long> map = new HashMap<>();
for (int i = 0; i < A.length; i++) {
P[i + 1] = P[i] + A[i];
if (P[i + 1] % M == 0) {
count++;
}
if (map.containsKey(P[i + 1] % M)) {
count += map.get(P[i + 1] % M);
}
if (!map.containsKey(P[i + 1] % M)) {
map.put(P[i + 1] % M, 0L);
}
map.put(P[i + 1] % M, map.get(P[i + 1] % M) + 1);
}
return count;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int M = scanner.nextInt();
long[] A = new long[N];
for (int i = 0; i < N; i++) {
A[i] = scanner.nextLong();
}
System.out.println(countHarmonySubarrays(A, M));
}
} const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
// 相同余数的前缀区间任选两个所构成的中间区间一定和谐(因为大的那个前缀区间求和减去小的前缀区间求和,刚好把那个多出来的余数减掉了,因此中间区间求和一定能被m整除)
void async function () {
// Write your code here
var arr=[];
while(line = await readline()){
arr.push(line)
}
// console.log("arr:",arr)
var firstline=arr[0].split(" ")
// console.log("firstline:",firstline)
var listlen=parseInt(firstline[0])
var harmonum=parseInt(firstline[1])
var list=arr[1].split(" ")
var lista=list.map(item=>parseInt(item))
// console.log('lista:',lista)
// //存放0-i位置的数组和的余数
// var leftnum=[]
var sumtmp=0
var ans=0
// //存放某个余数的出现个数
var map=new Map([[0,0]])
for(var i=0;i<listlen;i++){
sumtmp+=lista[i]
if(sumtmp%harmonum==0){ans+=1}
if(!map.has(sumtmp%harmonum)){
map.set(sumtmp%harmonum,1)
}else{
ans+=map.get(sumtmp%harmonum)
map.set(sumtmp%harmonum,map.get(sumtmp%harmonum)+1)
}
}
console.log(ans)
}() #include<bits/stdc++.h>
using namespace std;
int main(){
long int n = 0, m = 0;
cin>>n>>m;
vector<long int> vec(n);
for(auto &i : vec) cin>>i;
vector<long int> arr(m, 0);
long long int ans = 0;
for(auto i : vec){
vector<long int> old = arr;
for(int j = 0;j < m;j++){
arr[(i + j)%m] = old[j];
}
arr[i%m]++;
ans += arr[0];
}
cout<<ans;
return 0;
} #include <iostream>
#include<vector>
using namespace std;
int main()
{
int N, M;
cin >> N >> M;
vector <int> arr(N);
for (int i = 0; i < N; i++)
{
cin >> arr[i];
}
vector <int> map(M,0);
map[0] = 1;
long sum = 0;
long ans = 0;
for(int i = 0; i < N; i++)
{
sum += arr[i];
int index = sum % M;
ans += map[index]++;
}
cout << ans << endl;
system("pause");
return 0;
}