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 }

 

posted on 2015-09-11 22:05  hutaishi  阅读(163)  评论(0编辑  收藏  举报

导航