好久没打代码啦,今天lu一发百度之星,感觉还是学到不少东西的,写点收获。
第一题就是现在的HDU4831啦,题意很清楚,我一开始以为休息区也可以变为风景区,所以就不敢敲了,后来才得知数据里只会改风景区的,然后就有下面的思路。对于每个点我们用pre,post记录它前一个风景区和后一个风景区,对于每个休息区的热度,我们实际上只需要比较pre,post里哪个景点比较近,另外再开一个cnt数组记录每个风景区的点能到直接影响到的点的个数(其中不包括等距的点)。然后开一个树状数组去存热度为i的点有多少,每次更新lk,vk的时候,只需要将hot[lk]减去cnt[lk],然后修改hot[lk]再在hot[lk]上加上cnt[lk],但是有可能它前后的一些等距的点也会被更新,所以我们看pre[lk]和lk的中点是否存在,存在的话特别的更新一下,同样处理post[lk]. 但是好像本题能够直接模拟过掉,就是询问的时候扫一遍也可以,但是我感觉要是询问很多的时候会跪呀。。
第二题就是比赛的时候想了很久的题,没有思路,后来看了别人的代码才明白,纵向和横向是独立的,我们可以分开两个dp数组去记录横向走x步和纵向走k-x步有多少种走法,然后用组合数合起来就好.
最后一题我想应该很多人也是这样做的,先本地打表,然后上OEIS搜,果然搜到一个序列,然后经过对OEIS的资料进行分析就会发现,该数列的二次差分的数列an表示的是n有多少个奇数因子。然后不难发现如果能求出tau(n)(即n有多少个因子),那么就可以O(n)求出an。令我惊讶的是tau(n)居然能线性预处理,实在是太可怕了。。贴个链接以后好好学习http://blog.sina.com.cn/s/blog_82462ac30100y17u.html
到期末了,不能很舒心的欢乐的打代码了,要准备各科的复习了。。想想就觉得蛋疼。。
贴一下代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 |
//HDU4831<br>#pragma warning(disable:4996) #include <iostream> #include <cstring> #include <string> #include <vector> #include <cstdio> #include <algorithm> #include <cmath> #include <map> using
namespace std; #define ll long long #define maxn 100000 #define imp 1000000000 #define imp2 1000000001 int
bit[maxn + 50]; void
inc( int
x, int
val) { while
(x <= maxn){ bit[x] += val; x += x&(-x); } } int
query( int
x) { int
ret = 0; while
(x > 0){ ret += bit[x]; x -= x&(-x); } return
ret; } int
hot[10050]; int
dis[10050]; int
pre[10050]; int
post[10050]; int
cnt[10050]; map< int , int > mm; int
n,m; int
main() { int
T; cin >> T; int
ca = 0; while
(T--) { memset (cnt, 0, sizeof (cnt)); memset (pre, -1, sizeof (pre)); memset (post, -1, sizeof (post)); mm.clear(); memset (bit, 0, sizeof (bit)); scanf ( "%d" , &n); for
( int i = 1; i <= n; i++){ scanf ( "%d%d" , dis + i, hot + i); mm[dis[i]] = i; } int
mark = -1; for
( int i = 1; i <= n; i++){ if
(hot[i] == 0){ pre[i] = mark; } else { pre[i] = mark; mark = i; } } mark = -1; for
( int i = n; i >= 1; i--){ if
(hot[i] == 0){ post[i] = mark; } else { post[i] = mark; mark = i; } } for
( int i = 1; i <= n; i++){ if
(hot[i] == 0){ int
dpre =imp , dpost = imp2; if
(pre[i] != -1) dpre = abs (dis[pre[i]] - dis[i]); if
(post[i] != -1) dpost = abs (dis[post[i]] - dis[i]); if
(dpre == dpost) { inc(max(hot[pre[i]], hot[post[i]]), 1); hot[i] = max(hot[pre[i]], hot[post[i]]); } else { if
(dpre >= imp && dpost >= imp){ inc(0, 1); continue ; } if
(dpre < dpost){ cnt[pre[i]]++; inc(hot[pre[i]], 1); } else { cnt[post[i]]++; inc(hot[post[i]], 1); } } } else { inc(hot[i], 1); cnt[i]++; } } scanf ( "%d" , &m); printf ( "Case #%d:\n" , ++ca); char
s[5]; int
lk, vk; for
( int i = 0; i < m; i++){ scanf ( "%s" , s); if
(s[0] == ‘Q‘ ){ scanf ( "%d" , &lk); printf ( "%d\n" , query(lk)); } else { scanf ( "%d%d" , &lk, &vk); ++lk; inc(hot[lk], -cnt[lk]); hot[lk] = vk; inc(hot[lk], cnt[lk]); if
(post[lk] != -1 && !((dis[lk] + dis[post[lk]]) & 1)){ int
d = (dis[lk] + dis[post[lk]]) / 2; if
(mm.count(d)){ int
id = mm[d]; inc(hot[id], -1); hot[id] = max(hot[pre[id]], hot[post[id]]); inc(hot[id], 1); } } if
(pre[lk] != -1 && !((dis[lk] + dis[pre[lk]]) & 1)){ int
d = (dis[lk] + dis[pre[lk]]) / 2; if
(mm.count(d)){ int
id = mm[d]; inc(hot[id], -1); hot[id] = max(hot[pre[id]], hot[post[id]]); inc(hot[id], 1); } } } } } return
0; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 |
//HDU4832<br>#pragma warning(disable:4996) #include <iostream> #include <cstring> #include <string> #include <vector> #include <cstdio> #include <algorithm> #include <cmath> #include <map> using
namespace std; #define maxn 1200 #define ll long long #define mod 9999991 using
namespace std; int
dp1[maxn][maxn]; int
dp2[maxn][maxn]; int
row[maxn]; int
col[maxn]; int
c[maxn][maxn]; int
n, m, k, x, y; int
main() { c[1][0] = c[1][1] = 1; for
( int i = 2; i <= maxn-1; i++){ for
( int j = 0; j <= i; j++){ c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod; } } int
T; cin >> T; int
ca = 0; while
(T--) { scanf ( "%d%d%d%d%d" , &n, &m, &k, &x, &y); memset (dp1, 0, sizeof (dp1)); memset (dp2, 0, sizeof (dp2)); memset (row, 0, sizeof (row)); memset (col, 0, sizeof (col)); dp1[0][x] = 1; for
( int i = 1; i <= k; i++){ for
( int j = 1; j <= n; j++){ if
(j - 2 >= 0) dp1[i][j] = (dp1[i][j] + dp1[i - 1][j - 2]) % mod; (dp1[i][j] += ((dp1[i - 1][j - 1] + dp1[i - 1][j + 1]) % mod + dp1[i - 1][j + 2]) % mod) %= mod; } } dp2[0][y] = 1; for
( int i = 1; i <= k; i++){ for
( int j = 1; j <= m; j++){ if
(j - 2 >= 0) dp2[i][j] = (dp2[i][j] + dp2[i - 1][j - 2]) % mod; (dp2[i][j] += ((dp2[i - 1][j - 1] + dp2[i - 1][j + 1]) % mod + dp2[i - 1][j + 2]) % mod) %= mod; } } for
( int i = 0; i <= k; i++){ for
( int j = 1; j <= n; j++){ row[i] = (row[i] + dp1[i][j]) % mod; } } for
( int i = 0; i <= k; i++){ for
( int j = 1; j <= m; j++){ col[i] = (col[i] + dp2[i][j]) % mod; } } ll ans = 0; for
( int i = 0; i <= k; i++){ ans = (ans + (ll)row[i] * col[k - i] % mod*c[k][i]%mod) % mod; } printf ( "Case #%d:\n" , ++ca); printf ( "%I64d\n" , ans); } return
0; } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 |
//HDU4834<br>#pragma warning(disable:4996) #include <iostream> #include <cstring> #include <string> #include <vector> #include <cstdio> #include <algorithm> #include <cmath> #include <map> using
namespace std; #define N 10000050 #define ll long long using
namespace std; int
prime[N], p; int
cnt[N]; int
divv[N]; int
odd[N]; bool
iscomp[N]; void
getCount() { for
( int i = 2; i<N; i++) { if
(iscomp[i] == false ) { prime[p++] = i; cnt[i] = 1; divv[i] = 2; } for
( int j = 0; j < p&&i*prime[j] < N; j++) { iscomp[i*prime[j]] = true ; if
(i%prime[j] == 0) { divv[i*prime[j]] = divv[i] / (cnt[i] + 1)*(cnt[i] + 2); cnt[i*prime[j]] = cnt[i] + 1; break ; } else { cnt[i*prime[j]] = 1; divv[i*prime[j]] = divv[i] * divv[prime[j]]; } } } divv[1] = 1; } int
a[N]; ll ans[N]; int
main() { getCount(); for
( int i = 1; i < N; i++){ int
num = 0; int
tmp = i; while
(tmp % 2 == 0){ tmp >>= 1; num++; } odd[i] = divv[i] / (num + 1); } for
( int i = 1; i < N; i++){ a[i] = a[i - 1] + odd[i]; } ll sum = 0; for
( int i = 1; i < N; i++){ ans[i] = 1 + i + sum; sum += a[i]; } int
x; int
T; cin >> T; int
ca = 0; while
(T--){ scanf ( "%d" , &x); printf ( "Case #%d:\n" , ++ca); printf ( "%I64d\n" , ans[x]); } return
0; } |
HDU4831&&4832&&4834,布布扣,bubuko.com
原文地址:http://www.cnblogs.com/chanme/p/3751898.html