hdu CA Loves GCD(dp)

一道我想骂人的题,差点把我气炸了。

题意:

求一个数的集合中(非多重集,每个数只出现一次)所有子集的gcd的和。结果MOD10^8+7输出。

输入输出不说了,自己看吧,不想写了。

当时我真把它当作数论题来写了,以为可以推导出什么公式然后化简大量重复的操作的。结果最后也没找到。最后题解说是dp,我同学说是暴力,吐血10升。

然后弄出来dp方程之后还是反复的wa,方程明明没啥问题,愣是卡了2个小时找不出错误,心情烦躁的要命,坑爹的室友还各种看视频打游戏,还不带耳机,我自己只好带着耳机大声放音乐,最后连音乐都听不下去了,恶心的想吐。

后来实在无奈了查了下题解,但是没人用dp写,有个用莫比乌斯反演的orz,还有个用暴力的,不过其实有dp的思想在里面。当然这不重要,重要的是我看见了他MOD加的位置挺有意思的,然后猛然想到我的int爆了!因为需要一个小于10^8的数×一个小于1000的数,这个数有可能爆!我叉!特么这不是故意卡int的意思吗?最后把这个改了终于过了……此时距离比赛结束已经5个小时了,我*!

状态转移方程:

dp[i][a[i]] += 1;

dp[i][j] += dp[i-1][j];

dp[i][gcd[j][a[i]]] += dp[i-1][j];

其中gcd[][]是预处理离线出来的,要不然可能会超时。

状态dp[i][j]表示在前n个数的集合中,gcd为j的集合有多少个。

方程表示三种情况:

  1. 只有a[i]的集合。
  2. 不存在a[i],只存在前i-1个数中若干数的集合。
  3. 存在a[i],且存在前i-1个数中若干数的集合。

时间复杂度为O(n*maxn),其中maxn为a[]数组中的最大值。

具体见代码——

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 #define LL long long
 7
 8 const int N = 1010;
 9 const int Mod = 100000007;
10
11 int a[N];
12 LL dp[N][N];
13 int gcd[N][N];
14 int t, n;
15
16 int Gcd(int x, int y)
17 {
18     if(x < y)
19     {
20         int t = x;
21         x = y;
22         y = t;
23     }
24     while(y != 0)
25     {
26         int t = y;
27         y = x%y;
28         x = t;
29     }
30     return x;
31 }
32
33 void Table()
34 {
35     for(int i = 1; i < 1005; i++)
36     {
37         for(int j = 1; j <= i; j++)
38         {
39             gcd[i][j] = gcd[j][i] = Gcd(i, j);
40         }
41     }
42 }
43
44 int main()
45 {
46     //freopen("test.in", "r", stdin);
47     Table();
48     scanf("%d", &t);
49     for(int tm = 1; tm <= t; tm++)
50     {
51         scanf("%d", &n);
52         int maxn = 0;
53         for(int i = 0; i < n; i++)
54         {
55             scanf("%d", &a[i]);
56             maxn = maxn > a[i] ? maxn : a[i];
57         }
58         memset(dp, 0, sizeof(dp));
59         dp[0][a[0]] = 1;
60         for(int i = 1; i < n; i++)
61         {
62             dp[i][a[i]] += 1;                                       //转移方程1
63             for(int j = 1; j <= maxn; j++)
64             {
65                 dp[i][j] += dp[i-1][j];                             //转移方程2
66                 dp[i][gcd[j][a[i]]] += dp[i-1][j];                  //转移方程3
67                 dp[i][j] %= Mod;
68                 dp[i][gcd[j][a[i]]] %= Mod;
69             }
70         }
71         int ans = 0;
72         for(int i = 1; i <= maxn; i++)
73         {
74             ans += (dp[n-1][i]*i)%Mod;                  //这里小心dp如果是int可能会爆
75             ans %= Mod;
76         }
77
78         printf("%d\n", ans);
79     }
80     return 0;
81 }

自己确实挺弱的,还需要努力,但是今天确实非常烦!所有认为这些没什么好烦的,都是因为他没有身临其境的感觉。

时间: 2024-08-07 23:30:40

hdu CA Loves GCD(dp)的相关文章

hdu 5656 CA Loves GCD dp

CA Loves GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Problem Description CA is a fine comrade who loves the party and people; inevitably she loves GCD (greatest common divisor) too. Now, there are N diffe

hdu-5656 CA Loves GCD(dp+数论)

题目链接: CA Loves GCD Time Limit: 6000/3000 MS (Java/Others)     Memory Limit: 262144/262144 K (Java/Others) Problem Description CA is a fine comrade who loves the party and people; inevitably she loves GCD (greatest common divisor) too. Now, there are 

数学(GCD,计数原理)HDU 5656 CA Loves GCD

CA Loves GCD Accepts: 135 Submissions: 586 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) 问题描述 CA喜欢是一个热爱党和人民的优秀同♂志,所以他也非常喜欢GCD(请在输入法中输入GCD得到CA喜欢GCD的原因). 现在他有N个不同的数,每次他会从中选出若干个(至少一个数),求出所有数的GCD然后放回去. 为了使自己不会无聊,CA会把每

CA Loves GCD (BC#78 1002) (hdu 5656)

CA Loves GCD Accepts: 135 Submissions: 586 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) 问题描述 CA喜欢是一个热爱党和人民的优秀同♂志,所以他也非常喜欢GCD(请在输入法中输入GCD得到CA喜欢GCD的原因). 现在他有N个不同的数,每次他会从中选出若干个(至少一个数),求出所有数的GCD然后放回去. 为了使自己不会无聊,CA会把每

hdu 5656 CA Loves GCD

CA Loves GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 882    Accepted Submission(s): 305 Problem Description CA is a fine comrade who loves the party and people; inevitably she loves GC

hdu 5655 CA Loves Stick

CA Loves Stick Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 612    Accepted Submission(s): 214 Problem Description CA loves to play with sticks.One day he receives four pieces of sticks, he

HDU 5658 CA Loves Palindromic(回文树)

CA Loves Palindromic Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 301    Accepted Submission(s): 131 Problem Description CA loves strings, especially loves the palindrome strings. One day

HDU 4945 2048(dp)

题意:给n(n<=100,000)个数,0<=a[i]<=2048 .一个好的集合要满足,集合内的数可以根据2048的合并规则合并成2048 .输出好的集合的个数%998244353 . 比赛的时候想着1跟3可以合并成4 ....然后就越搞越复杂了.....2048玩得不多的我没有透彻的合并规则概念..... 看了题解写了发,妥妥地TLE...本地随意n=100,000都TLE了... 用dp[i][j]表示当前 i个2^j 的方案数 然后队友提醒优化,就是,当枚举到比如,value =

hdu 4870 Rating(概率DP&amp;高数消元)

Rating Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 714    Accepted Submission(s): 452 Special Judge Problem Description A little girl loves programming competition very much. Recently, she