vijos1090题解
来源:互联网 发布:淘宝商城布艺沙发 编辑:程序博客网 时间:2024/04/29 00:11
题目:
有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的值即可。
此题好像糊里糊涂看了人家的题解,然后就A了。
在这里膜拜那个大牛。SUM[i]是代表前i个数的和
当(SUM[i]-SUM[j]) MOD k=0 这时[j+1,i]就是满足的一个区间 一个方案了
而我们求的是(SUM[i]-SUM[j]) MOD k=0 这样的方案总个数
我们又可以推出 上式等价于SUM[i] MOD k=SUM[j] MOD k
所以我们就是求SUM[i] MOD k=SUM[j] MOD k 的方案个数了
假设 sum[i],sum[j],..sum[k](共bn个) 都是 MOD k 余数为k-1的sum
那么从上面bn个sum中任意选取两个就能得出(SUM[i]-SUM[j]) MOD k=0
那么在bn个sum中怎么配对呢
(下面的sum[bn]表示上述bn个sum中的第n个sum)
很简单 先是sum[b1]与sum[b2] sum[b3] ...sum[bn] (bn-1 个)
然后sum[b2]与sum[b3] sum[b4] ...sum[bn] (bn-2 个)
然后sum[b3]与sum[b4] sum[b5] ...sum[bn] (bn-3 个)
............
最后sum[bn-1]与sum[bn] ( 1 个)
方案总数=n-1+n-2+n-3+...+1=bn*(bn-1) div 2
所以 当sum mod k的余数为k-1时有bn*(bn-1) div 2个方案总数了
就这样依次得出余数为k-1 k-2 k-3 ...0的时候方案总数 再相加一下得出答案
所以在读入一个数的时候就计算sum然后计算sum mod k 的余数
而b[j]表示余数为j的sum个数 此时根据上面新得出的更新相应的b[j]
这样在读入完毕之后就可以根据b[j]直接计算总方案数了
特别值得注意的是!!!!
计算余数为0的方案总数时候还要加上b[0] 也就是b[0]*(b[0]-1) div 2+b[0]
为什么?? 因为余数为0的时候单独一个sum[i]就能成为一个方案了
还有比如div 2可以用shr 1 这样可以加快速度
var g:array[0..1000000] of longint; t,p,k,n,i:longint; tt,tot,x:int64;begin readln(n,k); tt:=0; tot:=0; for i:=0 to k do g[i]:=0; g[0]:=1; for i:=1 to n do begin read(x); tt:=tt+x; tt:=tt mod k; tot:=(tot+g[tt]) mod 1234567; inc(g[tt]); g[tt]:=g[tt] mod 1234567; end; writeln(tot);end.
0 0
- vijos1090题解
- Vijos1090. 连续数之和
- 前缀和(vijos1090连续数之和)
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解
- 题解~~~~
- 题解。。。。
- 题解
- 题解
- win8.1窗口动画设置
- Codeforces Round #231 (Div. 2)A-D
- Ubuntu 下 nginx , php , mysql 和 golang 的简单安装
- 当好但不够好时:今天我创业失败了
- 蓝桥杯基础练习--十进制转十六进制
- vijos1090题解
- jquery 控制textArea 随文本增加而变高
- 正则表达式总结
- C语言unlink删除文件
- 关于异常捕获后程序的去向
- c语言libcurl 使用实例get/post方法+c语言字符串处理
- SAP-EWM/ECC 系统后台配置
- 流密码加密文件的一个问题
- DDK怎么生成一个随机的数字