第四周 7.31-8.6

啦啦啦旅游拉。

7.31

补套BC。

 

HDU 5776 sum

离散数学课本题!小学生抽屉原理!

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 const int maxn = 1e5 + 10;
 5 int x[maxn];
 6 
 7 int main(void)
 8 {
 9     int T;
10     scanf("%d", &T);
11     while(T--)
12     {
13         int n, m;
14         scanf("%d %d", &n, &m);
15         for(int i = 1; i <= n; i++) scanf("%d", x + i);
16         if(n > m) puts("YES");
17         else
18         {
19             int ok = 0;
20             for(int i = 2; i <= n; i++) x[i] += x[i-1];
21             for(int i = 1; i <= n; i++)
22                 for(int j = 0; j < i; j++)
23                     if((x[i]-x[j]) % m == 0) {ok = 1;break;}
24             puts(ok ? "YES" : "NO");
25         }
26     }
27     return 0;
28 }
Aguin

 

HDU 5777 domino

答案最少也有n,要推倒旁边一个,高度就要加上距离。贪心的去掉最大的几个就好了。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn = 1e5 + 10;
 6 typedef long long LL;
 7 int d[maxn];
 8 
 9 int main(void)
10 {
11     int T;
12     scanf("%d", &T);
13     while(T--)
14     {
15         int n, k;
16         scanf("%d %d", &n, &k);
17         for(int i = 1; i < n; i++) scanf("%d", d + i);
18         if(k >= n) printf("%d\n", n);
19         else
20         {
21             sort(d + 1, d + n);
22             LL ans = n;
23             for(int i = 1; i <= n - k; i++) ans = ans + d[i];
24             printf("%I64d\n", ans);
25         }
26     }
27     return 0;
28 }
Aguin

 

HDU 5778 abs

素数定理,1e9之内素数间距离最大也就两百多。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn = 1e5 + 10;
 6 typedef long long LL;
 7 int d[maxn];
 8 
 9 int main(void)
10 {
11     int T;
12     scanf("%d", &T);
13     while(T--)
14     {
15         int n, k;
16         scanf("%d %d", &n, &k);
17         for(int i = 1; i < n; i++) scanf("%d", d + i);
18         if(k >= n) printf("%d\n", n);
19         else
20         {
21             sort(d + 1, d + n);
22             LL ans = n;
23             for(int i = 1; i <= n - k; i++) ans = ans + d[i];
24             printf("%I64d\n", ans);
25         }
26     }
27     return 0;
28 }
Aguin

 

HDU 5779 Tower Defence

先按题解那样搞。大概还要预处理一些2的阶乘、组合数、(2^k-1)^j之类的。

然后g[n][k]表示n个点,最短路为k的方案。

求个前缀和,再加上最短路无穷的情况。

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 typedef long long LL;
 5 const LL mod = 1e9 + 7;
 6 LL f[66][66][66], g[66][66];
 7 LL p[6666], c[66][66], e[66][66];
 8 
 9 int main(void)
10 {
11     p[0] = 1;
12     for(int i = 1; i <= 3600; i++) p[i] = p[i-1] * 2 % mod;
13 
14     for(int k = 1; k <= 60; k++)
15     {
16         e[k][0] = 1;
17         for(int j = 1; j <= 60; j++)
18             e[k][j] = e[k][j-1] * (p[k] - 1 + mod) % mod;
19     }
20 
21     for(int i = 0; i <= 60; i++) c[i][0] = c[i][i] = 1;
22     for(int i = 2; i <= 60; i++)
23         for(int j = 1; j < i; j++)
24             c[i][j] = (c[i-1][j-1] + c[i-1][j]) % mod;
25 
26 
27     f[1][0][1] = 1;
28     for(int i = 2; i <= 60; i++)
29     for(int d = 1; d <= i - 1; d++)
30     for(int j = 1; j <= i - d; j++)
31     {
32         for(int k = 1; k <= i - j - d + 1; k++)
33             f[i][d][j] = (f[i][d][j] + f[i-j][d-1][k] * e[k][j]) % mod;
34         f[i][d][j] = f[i][d][j] * p[j*(j-1)/2] % mod;
35         f[i][d][j] = f[i][d][j] * c[i-1][j] % mod;
36     }
37 
38     for(int n = 1; n <= 60; n++)
39     for(int k = 1; k < n; k++)
40     {
41         for(int i = k + 1; i <= n; i++)
42         for(int j = 1; j <= i - k; j++)
43         g[n][k] = (g[n][k] + f[i][k][j] * c[n-1][i-1] % mod * p[(n-i)*(n-i-1)/2]) % mod;
44     }
45 
46 
47     for(int n = 1; n <= 60; n++)
48     {
49         g[n][0] = p[(n-1)*(n-2)/2];
50         for(int k = 1; k <= 60; k++)
51         g[n][k] = (g[n][k] + g[n][k-1]) % mod;
52     }
53     int T;
54     scanf("%d", &T);
55     while(T--)
56     {
57         int n, k;
58         scanf("%d %d", &n, &k);
59         printf("%I64d\n", g[n][k-1]);
60     }
61 
62     return 0;
63 }
Aguin

 

HDU 5780 gcd

大概就是“古老的小技巧”的应用了。

不过学习了线性的逆元……

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 typedef long long LL;
 6 const LL mod = 1e9 + 7;
 7 const int maxn = 1e6 + 10;
 8 
 9 int phi[maxn];
10 void get_phi()
11 {
12     memset(phi, 0, sizeof(phi));
13     phi[1] = 1;
14     for(int i = 2; i < maxn; i++)
15     {
16         if(phi[i]) continue;
17         for(int j = i; j < maxn; j += i)
18         {
19             if(!phi[j]) phi[j] = j;
20             phi[j] = phi[j] / i * (i - 1);
21         }
22     }
23 }
24 
25 LL qpow(LL a, LL b)
26 {
27     LL ret = 1LL;
28     while(b)
29     {
30         if(b & 1) ret = ret * a % mod;
31         a = a * a % mod;
32         b >>= 1;
33     }
34     return ret;
35 }
36 
37 LL sum[maxn], inv[maxn], p[maxn];
38 int main(void)
39 {
40     get_phi();
41     for(int i = 1; i < maxn; i++) sum[i] = (sum[i-1] + phi[i]) % mod;
42 
43     inv[1] = 1;
44     for(int i = 2; i < maxn; i++) inv[i] = (mod - (mod / i) * inv[mod%i] % mod) % mod;
45 
46     int T;
47     scanf("%d", &T);
48     while(T--)
49     {
50         int x, n;
51         scanf("%d %d", &x, &n);
52 
53         if(x == 1) {puts("0"); continue;}
54 
55         LL ans = 0;
56         for(int i = 1; i <= n; i++)
57         {
58             int j = n / (n / i);
59             LL sd = (sum[n/i] + sum[n/i] + mod - 1) % mod;
60             LL tmp = (qpow(x, i) * (qpow(x, j - i + 1) - 1 + mod) % mod * inv[x-1] - j + i - 1 + mod) % mod;
61             ans = (ans + sd * tmp) % mod;
62             i = j;
63         }
64 
65         printf("%I64d\n", ans);
66 
67     }
68     return 0;
69 }
Aguin

 

posted @ 2016-07-31 20:07  Aguin  阅读(135)  评论(0编辑  收藏  举报