B. Modulo Sum
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given a sequence of numbers a1, a2, ..., an, and a number m.

Check if it is possible to choose a non-empty subsequence aij such that the sum of numbers in this subsequence is divisible by m.

Input

The first line contains two numbers, n and m (1 ≤ n ≤ 106, 2 ≤ m ≤ 103) — the size of the original sequence and the number such that sum should be divisible by it.

The second line contains n integers a1, a2, ..., an (0 ≤ ai ≤ 109).

Output

In the single line print either "YES" (without the quotes) if there exists the sought subsequence, or "NO" (without the quotes), if such subsequence doesn't exist.

Sample test(s)
Input
3 5
1 2 3
Output
YES
Input
1 6
5
Output
NO
Input
4 6
3 1 1 3
Output
YES
Input
6 6
5 5 5 5 5 5
Output
YES
Note

In the first sample test you can choose numbers 2 and 3, the sum of which is divisible by 5.

In the second sample test the single non-empty subsequence of numbers is a single number 5. Number 5 is not divisible by 6, that is, the sought subsequence doesn't exist.

In the third sample test you need to choose two numbers 3 on the ends.

In the fourth sample test you can take the whole subsequence.

鸽巢原理,不管怎么排,我们对数列求前缀和,在求模后得到pre1 , pre2 ,pre3 ,……pren,因为n>m,必存在prei = prej (i != j), 然后 (prei - prej) = 0 (mod m) 。

所以n>m时,为O(1)

然后剩下的部分n<=m时,用O(m*m)的dp即可。

然而没有我没有考虑鸽巢原理,用O(n*m)的dp加剪枝也过了,,,,,写dp要养成一个好习惯,那就是用当前的 已知解 去推 未知解 ,(反过来的话会碰上一些意想不到的问题),并且这样会自然形成一个剪枝

#include<bits/stdc++.h>
using namespace std;
typedef long long ll ;
const int M = 1e6 + 10 ;
int vis[1000 + 10] ;
ll pre[M] ;
int n , m ;
int dp[1000 + 10] ;
int d[1000 + 10] ; int main () {
scanf ("%d%d" , &n , &m) ;
bool flag = 0 ;
for (int i = 1 ; i <= n ; i ++) {
int x ;
scanf ("%d" , &x) ;
x = x % m ;
if (x == 0) flag = 1 ;
vis[x] ++ ;
}
if (flag) {
puts ("YES") ;
return 0 ;
}
int tmp = -1 ;
dp[0] = 1 ;
while (vis[++tmp] == 0 && tmp <= 1000) ;
//printf ("%d : num(%d)\n" , tmp , vis[tmp]) ;
for (int i = 1 ; i <= vis[tmp] ; i ++) {
int ans = tmp*i%m ;
if (ans == 0) ans = m ;
dp[ans] = m ;
}
if (dp[m]) {
puts ("YES") ;
return 0;
}
for (int i = tmp+1 ; i <= m ; i ++) {
if (vis[i] == 0) continue ;
//printf ("%d : num(%d)\n" , i , vis[i]) ;
for (int i = 0 ; i <= m ; i ++) d[i] = dp[i] ;
for (int j = 0 ; j <= m ; j ++) {
if (d[j] == 0) continue ;
for (int k = 1 ; k <= vis[i] ; k ++) {
int ans = (j+i*k)%m ;
if (ans == 0) ans = m ;
dp[ans] = 1 ;
}
}
if (dp[m]) {
puts ("YES") ;
return 0 ;
}
}
//for (int i = 1 ; i <= m ; i ++) printf ("%d " , dp[i]) ; puts ("") ;
puts ("NO") ;
return 0 ;
}

cf319.B. Modulo Sum(dp && 鸽巢原理 && 同余模)的更多相关文章

  1. Codeforces 1188C DP 鸽巢原理

    题意:定义一个序列的beauty值为序列中元素之差绝对值的最小值,现在给你一个数组,问所有长度为k的子序列的beauty值的和是多少? 思路:(官方题解)我们先解决这个问题的子问题:我们可以求出bea ...

  2. ACM数论之旅14---抽屉原理,鸽巢原理,球盒原理(叫法不一又有什么关系呢╮(╯▽╰)╭)

    这章没有什么算法可言,单纯的你懂了原理后会不会运用(反正我基本没怎么用过 ̄ 3 ̄) 有366人,那么至少有两人同一天出生(好孩子就不要在意闰年啦( ̄▽ ̄")) 有13人,那么至少有两人同一月 ...

  3. POJ 3370. Halloween treats 抽屉原理 / 鸽巢原理

    Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7644   Accepted: 2798 ...

  4. POJ 2356. Find a multiple 抽屉原理 / 鸽巢原理

    Find a multiple Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7192   Accepted: 3138   ...

  5. poj 2356 Find a multiple(鸽巢原理)

    Description The input contains N natural (i.e. positive integer) numbers ( N <= ). Each of that n ...

  6. poj2356 Find a multiple(抽屉原理|鸽巢原理)

    /* 引用过来的 题意: 给出N个数,问其中是否存在M个数使其满足M个数的和是N的倍数,如果有多组解, 随意输出一组即可.若不存在,输出 0. 题解: 首先必须声明的一点是本题是一定是有解的.原理根据 ...

  7. Find the duplicate Number (鸽巢原理) leetcode java

    问题描述: Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive ...

  8. POJ2356 Find a multiple 抽屉原理(鸽巢原理)

    题意:给你N个数,从中取出任意个数的数 使得他们的和 是 N的倍数: 在鸽巢原理的介绍里面,有例题介绍:设a1,a2,a3,……am是正整数的序列,试证明至少存在正数k和l,1<=k<=l ...

  9. hdu 1205 吃糖果【鸽巢原理】

    题目 这道题不难,看别人博客的时候发现大家都说用鸽巢原理,这是个什么鬼,于是乎百度之. 1.把某种糖果看做隔板,如果某种糖果有n个,那么就有n+1块区域,至少需要n-1块其他种糖果才能使得所有隔板不挨 ...

随机推荐

  1. C# 开源项目一

    商业协作和项目管理平台-TeamLab 网络视频会议软件-VMukti 驰骋工作流程引擎-ccflow [免费]正则表达式测试工具-Regex-Tester Windows-Phone-7-SDK E ...

  2. Python基本数据类型之set

    一.定义 set是一个无序且不重复的元素集合. 集合对象是一组无序排列的可哈希的值,集合成员可以做字典中的键.集合支持用in和not in操作符检查成员,由len()内建函数得到集合的基数(大小), ...

  3. JavaWeb学习总结-02 Tomcat 学习和使用

    一 Tomcat服务器端口的配置 Tomcat的所有配置都放在conf文件夹之中,里面的server.xml文件是配置的核心文件. 如果想修改Tomcat服务器的启动端口,则可以在server.xml ...

  4. IP地址、子网掩码、网关、DNS的关系

      什么是IP地址所谓IP地址就是给每个连接在Internet上的主机分配的一个32bit地址.按照TCP/IP协议规定,IP地址用二进制来表示,每个IP地址长32bit,比特换算成字节,就是4个字节 ...

  5. Mybatis的mapper文件中$和#的区别

    一般来说,我们使用mybatis generator来生成mapper.xml文件时,会生成一些增删改查的文件,这些文件中需要传入一些参数,传参数的时候,我们会注意到,参数的大括号外面,有两种符号,一 ...

  6. Yocto开发笔记之《串口驱动调试》(QQ交流群:519230208)

    QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 ======================================================== 串口驱动各 ...

  7. UrlEncode编码/UrlDecode解码 - 站长工具

    http://tool.chinaz.com/tools/urlencode.aspx

  8. Jquery学习之基础篇二

    1.Jquery添加元素的方法 append() - 在被选元素的结尾插入内容 prepend() - 在被选元素的开头插入内容 after() - 在被选元素之后插入内容 before() - 在被 ...

  9. cannot start session without errors

    访问phpmyadmin出现如标题错误,解决方案如下: cd /var/lib/php 更改目录权限chown nginx:nginx -R session/ That's All!

  10. JavaWeb学习总结(三)——Tomcat服务器学习和使用(二) 包含https 非对称秘钥 NB

    JavaWeb学习总结(三)--Tomcat服务器学习和使用(二) 一.打包JavaWeb应用 在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命 ...