Vijos 连续数之和 (组合数学)

描述

有n个正整数排成一行。你的目的是要从中取出一个或连续的若干个数,使它们的和能够被k整除。

例如,有6个正整数,它们依次为1、2、6、3、7、4。若k=3,则你可以取出1、2、6,或者2、6、3、7,也可以仅仅取出一个6或者3使你所取的数之和能被3整除。当然,满足要求的取法不止以上这4种。事实上,一共有7种取法满足要求。

给定n和k,以及这n个数。你的任务就是确定,从这n个数中取出其中一个数或者若干连续的数使它们的和能被k整除有多少方法。

由于取法可能很多,因此你只需要输出它mod 1234567的值即可。

格式

输入格式

第一行有两个正整数,分别代表n和k。输入数据保证有n<=500 000,k<=100 000。

以下n行每行一个正整数。这些正整数保证都不大于10 000。

输出格式

一个正整数。它应该是你的答案mod 1234567的结果。

样例1

样例输入1

6 3
1
2
6
3
7
4

Copy

样例输出1

7

Copy

限制

各个测试点1s

来源

Matrix67 根据经典问题改编

 1 /*
 2     我们设sum为前缀和
 3     首先要知道
 4     (sum[j]-sum[i])%k==0 --> sum[j]%k==sum[i]%k
 5     假设 sum[k]==sum[l]  那么 sum[k]-sum[l]==0
 6     也就是 在[l+1,k]这段区间连续的和可以被k整除
 7     那么假设 sum[i],sum[j],..sum[k](共bn个)
 8     都是 MOD k 余数为k-1的sum
 9     只需要从中任意取两个 就可以构成一个连续的区间的和可以整除k
10
11     注意余数为0 要单独加一次
12 */
13 #include<cstdio>
14 #include<iostream>
15 #define MAXN 500010
16 #define MOD 1234567
17
18 using namespace std;
19
20 int n,k;
21 long long ans,a[MAXN];
22
23 int b[100010];
24
25 inline void read(int&x) {
26     x=0;int f=1;char c=getchar();
27     while(c>‘9‘||c<‘0‘) {if(c==‘-‘) f=-1;c=getchar();}
28     while(c>=‘0‘&&c<=‘9‘) {x=(x<<1)+(x<<3)+c-48;c=getchar();}
29     x=x*f;
30 }
31
32 inline int c(int N,int M) {
33     return (N*(N-1)/2)%MOD;
34 }
35
36 int main() {
37     int temp=0;
38     read(n);read(k);
39     for(int i=1;i<=n;i++) {
40         read(temp);
41         a[i]=a[i-1]+temp;
42         ++b[a[i]%k];
43     }
44     ans+=b[0];
45     for(int i=0;i<k;i++) {
46         if(b[i]>=2)
47           ans=(ans+c(b[i],2))%MOD;
48     }
49     printf("%lld\n",ans);
50     return 0;
51 }

代码

时间: 2024-08-27 08:07:40

Vijos 连续数之和 (组合数学)的相关文章

前缀和(vijos1090连续数之和)

描述 有n个正整数排成一行.你的目的是要从中取出一个或连续的若干个数,使它们的和能够被k整除. 例如,有6个正整数,它们依次为1.2.6.3.7.4.若k=3,则你可以取出1.2.6,或者2.6.3.7,也可以仅仅取出一个6或者3使你所取的数之和能被3整除.当然,满足要求的取法不止以上这4种.事实上,一共有7种取法满足要求. 给定n和k,以及这n个数.你的任务就是确定,从这n个数中取出其中一个数或者若干连续的数使它们的和能被k整除有多少方法. 由于取法可能很多,因此你只需要输出它mod 1234

[算法]正整数分解为几个连续自然数之和

题目:输入一个正整数,若该数能用几个连续正整数之和表示,则输出所有可能的正整数序列. 一个正整数有可能可以被表示为n(n>=2)个连续正整数之和,如: 15=1+2+3+4+5 15=4+5+6 15=7+8 有些数可以写成连续N(>1)个自然数之和,比如14=2+3+4+5:有些不能,比如8.那么如何判断一个数是否可以写成连续N个自然数之和呢? 一个数M若可以写成以a开头的连续n个自然数之和,则M=a+(a+1)+(a+2)+-+(a+n-1)=n*a+n*(n-1)/2,要求a!=0,否则

连续正整数之和(华东师范大学OJ-3025)

题目描述:一个正整数有可能可以被表示为 n(n>=2) 个连续正整数之和,如: 15=1+2+3+4+5 15=4+5+6 15=7+8 请编写程序,根据输入的任何一个正整数,找出符合这种要求的所有连续正整数序列. 输入数据:一个正整数,以命令行参数的形式提供给程序. 输出数据:在标准输出上打印出符合题目描述的全部正整数序列,每行一个序列,每个序列都从该序列的最小正整数开始.以从小到大的顺序打印.如果结果有多个序列,按各序列的最小正整数的大小从小到大打印各序列.此外,序列不允许重复,序列内的整数

正整数分解为几个连续自然数之和

题目:输入一个正整数,若该数能用几个连续正整数之和表示,则输出所有可能的正整数序列. 一个正整数有可能可以被表示为n(n>=2)个连续正整数之和,如: 15=1+2+3+4+5 15=4+5+6 15=7+8 有些数可以写成连续N(>1)个自然数之和,比如14=2+3+4+5:有些不能,比如8.那么如何判断一个数是否可以写成连续N个自然数之和呢? 一个数M若可以写成以a开头的连续n个自然数之和,则M=a+(a+1)+(a+2)+-+(a+n-1)=n*a+n*(n-1)/2,要求a!=0,否则

最大连续元素之和

Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14. Input The first line of the input contains an integer T(1<=T<

LeetCode 18. 4Sum (四数之和)

Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. Note: The solution set must not contain duplicate quadruplets. For exampl

2015年百度之星初赛(1) --- B 找连续数

找连续数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 179    Accepted Submission(s): 65 Problem Description 小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的. 现在小度熊增加题目难度,他不想知道是否有这样的 k 的区

给定数组A,大小为n,现给定数X,判断A中是否存在两数之和等于X

题目:给定数组A,大小为n,现给定数X,判断A中是否存在两数之和等于X 思路一: 1,先采用归并排序对这个数组排序, 2,然后寻找相邻<k,i>的两数之和sum,找到恰好sum>x的位置,如果sum=x则返回true, 3,找到位置后,保持i不变,从k处向前遍历,直到找到A[k]+A[i]等于x,并返回TRUE,如果找不到,则返回false. 论证步骤3:当前找到的位置恰好A[k]+A[i]>x,且前一位置的sum<x: 所以A[i]前面的数(不包括A[i])无论取哪两个数都

JavaScript-3.1--获取用户的输入,输出用户输入的两数之和---ShinePans

提示用户输入两个数,然后输出用户输入的两数之和 第一次输入 ,输入处为空 第二个输入,输入处为默认27  (这里强调语句的使用) <html> <head> <meta http-equiv="content-type" content="text/html;charset=GB2312"/> <title> 3.1 让用户输入两个数字,然后输出相加的结果 </title> </head> &l