首页 > 其他分享 > k 倍区间(同余定理,组合数)

k 倍区间(同余定理,组合数)

时间:2023-06-11 10:23:55浏览次数:42  
标签:前缀 int 定理 ++ 区间 sum 同余

题目描述

给定一个长度为 N 的数列,1,2,⋯A1​,A2​,⋯AN​,如果其中一段连续的子序列 ,+1,⋯(≤)Ai​,Ai+1​,⋯Aj​(i≤j) 之和是 K 的倍数,我们就称这个区间 [,][i,j] 是 K 倍区间。

你能求出数列中总共有多少个 K 倍区间吗?

输入格式

第一行包含两个整数 N 和 K(1≤,≤105)(1≤N,K≤105)。

以下 N 行每行包含一个整数 Ai​(1≤≤105)(1≤Ai​≤105)。

输出格式

输出一个整数,代表 K 倍区间的数目。

输入输出样例

输入 #1
5 2
1  
2  
3  
4  
5  
输出 #1
6
本题的第一思路就前缀和,本以为时间限制是2s完全够我开n2,但还是tle了,想不到优化的方案
没想到使用数学知识来优化:
利用同余定理:当 a mod k=b mod k 时,∣a−b∣modk=0。
若设前缀和数组为 s,则我们知道,si​ 就表示 0+1+2+...+a0​+a1​+a2​+...+ai​
那么我们用另一个数组存储每个前缀和的模数,当找到相同模数时,中间的那段即为 k 的倍数。
统计前缀和除以 k 后余数的数量,然后两两组合计算答案。
其实就是计算 ∑=0−1[]2∑i=0k−1​Ccnt[i]2​,利用组合数两两组合;
然后 00 的数量要特判一下。
比如计算区间 [1,5][1,5] 的和,应该是 sumd5​−sumd0​,所以 sumd0​ 也要统计进去,而 sumd0​=0
所以特别处理一下就可以了:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
long long n,k,a[N],s[N],res,sum;
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        sum=(sum+a[i])%k;
        s[sum]++;//利用桶来储存数量
    }
    s[0]++;//这里的0要特判一下,毕竟前面
    for(int i=0;i<k;i++)
        res+=s[i]*(s[i]-1)/2;//组合数两两组合公式
    cout<<res;
    return 0;
}

还有另外一种不适用组合数的方法:

每次取这个数组的前缀和与 k 取模,并加上这个前缀和出现的次数。如果不止一次出现,那么上一次出现的位置到这一次出现的位置之间的数的和就一定可以被 k 整除,即为 k 倍区间。

另外,如果这个前缀和已经可以直接被 k 整除的话,也算 k 倍区间。

输出最后的个数即可:

 

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
long long  a[N],res,s[N],n,k,ans[N];
int main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        s[i]=(s[i-1]+a[i])%k;
        res+=ans[s[i]];//解释一下这里为什么要先加再++
        //因为同余定理是两个同余的数合并才是一个k倍区间
        //模拟一下,如果先++再加的话,此时余这个数的个数只有一个,不能算入k倍区间;
        ans[s[i]]++;
    }
    cout<<res+ans[0];
}

标签:前缀,int,定理,++,区间,sum,同余
From: https://www.cnblogs.com/o-Sakurajimamai-o/p/17472554.html

相关文章

  • 信道容量与香农定理、信源编码、信道编码总结
    1信道容量定义1.1信道容量:信道中平均每个符号所能传递的最大互信息量$I(X;Y)$$C=\mathop{max}\limits_{p(x)}{I(X;Y)}$单位:bit/符号1.2单位时间t内信道容量:$C_t=\frac{C}{t}$单位:bit/s1.3最佳输入概率$p(x)$分布时,传输的信息能达到信道容量1.4信道容量反映信道特性,表示信......
  • R语言无套利区间模型期货期现研究:正向套利和反向套利次数、收益率分析华泰柏瑞300ETF
    全文链接:http://tecdat.cn/?p=31973最近我们被客户要求撰写关于无套利区间模型的研究报告,包括一些图形和统计输出。股指期货的套利交易有助于股指期货实现其价格发现以及风险规避的功能,因此提高套利交易的效率,对于发挥股指期货在经济发展中的作用有着重要的意义本文帮助客户对......
  • 75 验证码 大小写字母a_Z(随机区间需要去掉6个非法的值,不合法+6)和数字拼接
    packagecom.fqs.test;importjava.util.Random;publicclasshello{publicstaticvoidmain(String[]args){//定义方法实现随机产生一个5位的验证码//验证码格式长度5//前四位是大写的字母或者小写的字母abcD5//最后一位......
  • 区间PD之石子合并
    设有 N堆石子排成一排,其编号为 1,2,3,…,N每堆石子有一定的质量,可以用一个整数来描述,现在要将这 N堆石子合并成为一堆。每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合并后与这两堆石子相邻的石子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同。例如有......
  • 区间 mex 问题
    可以考虑以下P2709的做法。先用莫队取下出现在\([l_i,r_i]\)的位置的数,然后二分求得\(ask(x)=x\)的最大\(x\)就是答案。注意\(0\)不能加入树状数组,于是先给所有数加\(1\)。块长取\(n^{0.55}\)最佳。#include<bits/stdc++.h>usingnamespacestd;constintN=......
  • # DP进阶训练:区间dp + 数位dp + 状压dp
    DP进阶训练:区间dp+数位dp+状压dpvj题单A.MultiplicationPuzzle(区间dp)题意:首先这道题题意大概是:n个数字,每次你能拿走一个数字(除了两边的),贡献是这个数字和两边两个数字的成绩。最后题目要求你按任意顺序拿走n-2个数字,使得贡献和最小。分析:顺序:首先能想到是个d......
  • 树状数组详解——本质上就是空间换时间,可以解决大部分基于区间上的更新以及求和问题
     943.区间和查询-Immutable 中文 English 给一个整数数组nums,求出下标从i到j的元素和(i≤j),i跟j对应的元素也包括在内。 样例样例1输入:nums=[-2,0,3,-5,2,-1]sumRange(0,2)sumRange(2,5)sumRange(0,5)输出:1-1-3解释:sumRange(0,2)->(-2......
  • 强化学习基础篇【1】:基础知识点、马尔科夫决策过程、蒙特卡洛策略梯度定理、REINFORCE
    强化学习基础篇【1】:基础知识点、马尔科夫决策过程、蒙特卡洛策略梯度定理、REINFORCE算法1.强化学习基础知识点智能体(agent):智能体是强化学习算法的主体,它能够根据经验做出主观判断并执行动作,是整个智能系统的核心。环境(environment):智能体以外的一切统称为环境,环境在与智能体......
  • POJ2154(Pólya定理与欧拉函数优化)
    题目:Color 题意:将正n边形的n个顶点用n种颜色染色,问有多少种方案(答案modp,且可由旋转互相得到的算一种) 先说说Pólya定理设Q是n个对象的一个置换群,用m种颜色涂染这n个对象,一个对象涂任意一种颜色,则在Q作用下不等价的方案数为:   |Q|为置换群中置换的个数,为将置换q表示成不相杂......
  • hdu 5768 - 中国剩余定理 + 容斥
    题解思路:利用中国剩余定理解决多个同余问题,这里需要再加一项mn=7,an=0,这样才能求出7的倍数的解,然后再需要用到容斥,2^15枚举就行了。1.扩展欧几里得: 我们观察到:欧几里德算法停止的状态是:a=gcd(a,b),b=0,那么,这是否能给我们求解xy提供一种思路呢?因为,这时候,只要a=gc......