cf 319 div 2 Modulo Sum 数论+DP

                   Modulo Sum

题目抽象:给你你一个整数数组,能否从中取出一些树,使得他们的和能被m整除。

分析:见代码注释。

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 const int MS = 1000005;
 5 int n, m;
 6 int cnt[MS], r[MS], tem[MS];
 7 int main() {
 8     scanf("%d%d", &n, &m);
 9     memset(cnt, 0, sizeof(cnt));
10     for (int i = 0; i < n; i++) {
11         scanf("%d", &r[i]);
12         r[i] %= m;
13         cnt[r[i]]++;   //  统计不同余数的个数
14     }
15     memset(r, 0, sizeof(r));     //初始化余数i不能构成
16     for (int i = 0; i < m; i++) {
17         if (cnt[i] > 0) {      //处理余数i
18             int x = 1;
19             while (cnt[i] > 0) {
20                 int y = x < cnt[i] ? x : cnt[i];
21                 cnt[i] -= y;
22                 x *= 2;                //  倍增算法处理。
23                 int z = (i * y) % m;    //  y个余数i构成余数z.
24                 for (int j = 0; j < m; j++) {
25                     if (r[j])
26                         tem[(j + z) % m] = 1;    // 在余数j的基础上构成余数(j + z) %m
27                 }
28                 for (int j = 0; j < m; j++) {
29                     r[j] += tem[j];     //  更新能构成的余数
30                     tem[j] = 0;
31                 }
32                 r[z] = 1;     //余数z能构成
33             }
34             if (r[0] > 0)
35                 break;
36         }
37     }
38     if (r[0] > 0)
39         printf("YES\n");
40     else
41         printf("NO\n");
42     return 0;
43 }
时间: 2024-10-06 14:27:32

cf 319 div 2 Modulo Sum 数论+DP的相关文章

CF #319 div 2 D

这道题算不算脑洞题.. 可以发现,当一个排列中有循环节时长度为1或2时可能有解.当为1时,只需把全部点都连到这个题即可,当为2时,就要求所有循环节长度均为偶数,这很容易理解,因为如果存在为奇数,它们之间连线之后就可以形成环或者不存在的情况了.把其他循环节上的点分别连到这两个点上即可.为什么是2呢?因为,可以理解为树上的一条连连T_T 666666 #include <iostream> #include <cstdio> #include <algorithm> #in

CF #319 div 2 E

在一个边长为10^6正方形中,可以把它x轴分段,分成1000段.奇数的时候由底往上扫描,偶数的时候由上往下扫描.估计一下这个最长的长度,首先,我们知道有10^6个点,则y邮方向最多移动10^3*10^6.对于x轴方向,如果都在一个段内,则最多移动 10^3*10^6,如果均不在一个段内,最多就2000*10^3.比限制长度肯定要小. #include <iostream> #include <cstdio> #include <algorithm> using name

codeforces #319 B - Modulo Sum (抽屉原理,dp)

B - Modulo Sum Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Description 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 

CF #374 (Div. 2) C. Journey dp

1.CF #374 (Div. 2)    C.  Journey 2.总结:好题,这一道题,WA,MLE,TLE,RE,各种姿势都来了一遍.. 3.题意:有向无环图,找出第1个点到第n个点的一条路径,经过的点数要最多. #include<bits/stdc++.h> #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,

CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组(转)

转载自:http://www.cnblogs.com/icode-girl/p/5744409.html 题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有出现偶数次的数异或的值. 思路:容易想到,把区间内的所有的数都异或得到的是出现奇数次的数的值,然后再异或该区间内的所有出现过的数(每个数只统计一次),得到的ans了. 第一个问题:得到询问区间的

CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组

题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有出现偶数次的数异或的值. 思路:容易想到,把区间内的所有的数都异或得到的是出现奇数次的数的值,然后再异或该区间内的所有出现过的数(每个数只统计一次),得到的ans了. 第一个问题:得到询问区间的所有数的异或值,由 a[l~r] ^ a[0~(l-1)] = a[l~r] 可以用数组all_xor[i

Codeforces Round 319 # div.1 &amp; 2 解题报告

Div. 2 Multiplication Table (577A) 题意: 给定n行n列的方阵,第i行第j列的数就是i*j,问有多少个格子上的数恰为x. 1<=n<=10^5, 1<=x<=10^9 题解: 送分题…对于每一行,判断是否存在数x即可…也可以枚举x的因子判断是否出现在表内… #include<cstdio>#include<cstring>inlineint read(){int s =0;char c;while((c=getchar())

CF #371 (Div. 2) C、map标记

1.CF #371 (Div. 2)   C. Sonya and Queries  map应用,也可用trie 2.总结:一开始直接用数组遍历,果断T了一发 题意:t个数,奇变1,偶变0,然后与问的匹配. #include<bits/stdc++.h> #define max(a,b) a>b?a:b #define F(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,sizeof(a)) #define INF

CF #375 (Div. 2) D. bfs

1.CF #375 (Div. 2)  D. Lakes in Berland 2.总结:麻烦的bfs,但其实很水.. 3.题意:n*m的陆地与水泽,水泽在边界表示连通海洋.最后要剩k个湖,总要填掉多少个湖,然后输出. #include<bits/stdc++.h> #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,s