SDUT3173 有多少个连续子序列的和能被k整除
2016-02-02 14:25
309 查看
题目描述
Edward 得到了一个长度为 N 的整数序列,他想找出这里面有多少个“幸运的”连续子序列。一个连续子序列被称为“幸运的”,当且仅当该子序列内的整数之和恰好是 K 的整数倍数。他请求你写一个程序来计算他喜欢的连续子序列个数。输入
输入第一行是一个整数 T,表示有 T 组数据。每组数据第一行是两个整数 N (1 <= N <= 10^6 ), K (1 <= K <= 10^9 )。接下来的一行包含 N 个整数 A i (|A i | <= 10^9 )。输出
对于每组测试数据,输出一行仅包含一个整数,表示 Edward 喜欢的连续子序列数量。示例输入
2 5 3 1 2 3 4 1 6 2 1 2 1 2 1 2
示例输出
4 9
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=3173
范围很大不能用O(n2)的做法。这时考虑前缀和同模做差。但是很难想到。
比如,有a b c d e,(a+b)%mod=k,(a+b+c+d+e)%mod也=k,那么(c+d+e)%mod=0,即该子序列是mod的整数倍数。
#include<iostream>#include<algorithm>#include<string>#include<map>#include<cmath>#include<string.h>#include<stdlib.h>#include<cstdio>#define ll long longusing namespace std;ll x[1000001];ll C(ll m,ll n){ll i,j,sum=1;for (i=m,j=0;j<n;j++,i--)sum=sum*i/(j+1);return sum;}int main(){ll t,n,m;scanf("%lld",&t);while(t--){scanf("%lld%lld",&n,&m);x[0]=0;ll cnt=0;ll w;for(ll i=1;i<=n;++i){cin>>w;x[i]=((x[i-1]+w)%m+m)%m; //因为w有可能是负的}sort(x,x+n+1);ll s=1;for(ll i=1;i<=n;++i){if(x[i]==x[i-1])s++;else{cnt+=C(s,2);s=1;}}cnt+=C(s,2);printf("%lld\n",cnt);}return 0;}
相关文章推荐
- Linux Shell常用技巧(七) find xargs
- Builder模式
- myeclipse中java文件头注释格式设置
- 2016年要学会用存储过程向关联的几张表里面插入数据。
- C和C++库中的排序函数——sort与qsort解析
- iOS视图控制对象生命周期-init、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear、viewDidDisappear的区别及用途
- RMQ算法
- Windows编程之COM组件
- Android日志系统驱动程序Logger源代码分析
- puppet之自定义fact(转载)
- Hive 3、Hive 的安装配置(本地derby模式)
- ROS 进阶学习笔记(12) - Communication with ROS through USART Serial Port
- 258 Add Digits
- Linux Shell常用技巧(六) sort uniq tar split
- redis(java)
- WC2016 挑战NPC
- uva1267 - Network
- 在listView适配器的内存优化给点击事件带来的麻烦
- [树状数组+上升子序列] HDU 3030 Increasing Speed Limits
- 【SCOI2013】【BZOJ3323】多项式的运算