正睿20NOIp前冲刺day6

估分:100+20+0+10=130

实际:爆0

T1:

  最开始写了个菊花图,忘记return了,是菊花图的答案都输出了两遍,没分了

  把权值取对数,然后做最大独立集的和就行了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 
 8 typedef long long LL;
 9 
10 const int N = 200010;
11 const int mod = 1e9 + 7;
12 
13 int n;
14 LL w[N], d[N][2];
15 double s[N], f[N][2];
16 int h[N], num[N << 1], nex[N << 1], dqx;
17 
18 
19 void add(int a, int b)
20 {
21     num[dqx] = b;
22     nex[dqx] = h[a];
23     h[a] = dqx++;
24 }
25 
26 void dfs(int u, int fa)
27 {
28     d[u][0] = 1, d[u][1] = w[u];
29     f[u][0] = log10(1), f[u][1] = s[u];
30     for (int i = h[u]; ~i; i = nex[i])
31     {
32         int j = num[i];
33         if (j == fa) continue;
34         dfs(j, u);
35         if (f[j][1] > f[j][0])
36         {
37             f[u][0] += f[j][1];
38             d[u][0] = d[u][0] * d[j][1] % mod;
39         }
40         else
41         {
42             f[u][0] += f[j][0];
43             d[u][0] = d[u][0] * d[j][0] % mod;
44         }
45 
46         f[u][1] += f[j][0];
47         d[u][1] = d[u][1] * d[j][0] % mod;
48     }
49 }
50 
51 int main()
52 {
53     scanf("%d", &n);
54     for (int i = 1; i <= n; i++) scanf("%lld", &w[i]), s[i] = log10(w[i]);
55 
56     memset(h, -1, sizeof(h));
57     for (int i = 1; i < n; i++)
58     {
59         int a, b;
60         scanf("%d%d", &a, &b);
61         add(a, b), add(b, a);
62     }
63 
64     dfs(1, 0);
65 
66     LL ans = d[1][0];
67     if (f[1][1] > f[1][0]) ans = d[1][1];
68     printf("%lld", ans);
69 }
View Code

T2:

  正解思路想到了,但写的时候代码写错了,就以为思路是错的,就写20pts暴力去了,但忘检验枚举的2*x大于n的情况了,没分了

  把一串x,2x,4x,8x……归位一组,就可以发现每个奇数是一组的开头,A和B就在一组中交叉选数,A:x,4x,16x……,B:2x,8x,32x……,这样就发现若一个组的数的个数为偶,则他对答案的贡献是2(A一半B一半),若为奇,则多的一个可以给A可以给B,A的集合大小限制就从这变的,设个数为奇的组的个数为O,把所有个数为奇的组多的那一个都给B,此时A的集合大小就是最小的,设为L,若要求A的大小为m,则就要从个数为奇的组中抽m-L个组把多的一个给A,答案就是C(O,m-L)

  求组数时可以枚举组的长度(元素个数),n/2l得的数k,就表示长度大于等于l的组有k/2(上取整)个,因为每组最大的一个肯定是x*2l,k就表示最大的一个x,又因为x是奇数,所以组数就是1~k中的奇数个数,就是k/2(上取整)个

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 #define int long long
 8 
 9 const int mod = 1e7 + 19;
10 
11 int fac[mod+1000], f[65];
12 
13 int qmul(int a, int k, int mod)
14 {
15     int res = 1;
16     while (k)
17     {
18         if (k & 1) res = res * a % mod;
19         a = a * a % mod;
20         k >>= 1;
21     }
22     return res;
23 }
24 
25 int inv(int x)
26 {
27     return qmul(fac[x], mod - 2, mod);
28 }
29 
30 int C(int n, int m)
31 {
32     if (m > n) return 0;
33     return fac[n] * inv(m) % mod * inv(n - m) % mod;
34 }
35 
36 int Lucas(int a, int b)
37 {
38     if (!b) return 1;
39     if (b < 0) return 0;
40     return C(a % mod, b % mod) * Lucas(a / mod, b / mod) % mod;
41 }
42 
43 signed main()
44 {
45     int n, q;
46     scanf("%lld%lld", &n, &q);
47 
48     fac[0] = 1;
49     for (int i = 1; i <= mod; i++) fac[i] = fac[i - 1] * i % mod;
50 
51     int p = 1;
52     for (int i = 0; i <= 60; i++)
53     {
54         f[i] = ceil(1.0 * (n / p) / 2);
55         p *= 2;
56     }
57 
58     int least = 0, odd = 0, eve = 0;
59     for (int i = 1; i <= 60; i++)
60     {
61         least += (f[i - 1] - f[i]) * (i / 2);
62         if (i & 1) odd += f[i - 1] - f[i];
63         else eve += f[i - 1] - f[i];
64     }
65 
66     int res = qmul(2, eve, mod);
67     while (q--)
68     {
69         int x;
70         scanf("%lld", &x);
71         printf("%lld\n", res * Lucas(odd, x - least) % mod);
72     }
73 }
View Code

T3:

  不会

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 
 9 const int N = 100010;
10 
11 int n;
12 int f[N], g[N], s[N], mod;
13 
14 int get(int x) 
15 {
16     if (x > n) return 0;
17 
18     memset(f, 0, sizeof(f));
19     memset(g, 0, sizeof(g));
20     memset(s, 0, sizeof(s));
21 
22     f[0] = 1; 
23     int b = max(300, x);
24     for (int i = x; i < b; i++) 
25     {
26         for (int j = 0; j <= n; j++) 
27         {
28             if (j + i <= n) f[j + i] = (f[j + i] + f[j]) % mod;
29         }
30     }
31 
32     g[0] = 1, s[0] = 1;
33     for (int i = 1; i <= n / b; i++) 
34     {
35         int t = i * b;
36         for (int j = i; j + t <= n; j++) g[j] = (g[j] + g[j - i]) % mod;
37         for (int j = 0; j + t <= n; j++) s[j + t] = (s[j + t] + g[j]) % mod;
38     }
39     int ans = 0;
40     for (int i = 0; i <= n; i++) ans = (ans + (f[i] * 1LL * s[n - i]) % mod) % mod;
41     return ans;
42 }
43 
44 int main()
45 {
46     int x, y;
47     scanf("%d%d%d%d", &x, &y, &n, &mod);
48     int ans = get(x);
49     ans = (ans + (mod - get(y + 1))) % mod;
50     printf("%d", ans);
51 }
View Code

 

T4:

  之前加的A或E为空集就返回的条件忘删以及只有一个字符的时候没特判,就没分

  不会

总结:

  总是思路想到了,要么代码不会写,要么写炸,代码能力还是差,以后要多练练,至少代码的得分和估分差不远才行,代码的常数大小也要多练练。拍的时候也不只拍极限数据了,还是要多拍随机的数据才行,这次就没多拍随机数据导致一二题出了问题。

 

posted on 2020-10-19 17:36  ArrogHie  阅读(114)  评论(0编辑  收藏  举报