码迷,mamicode.com
首页 > 其他好文 > 详细

HDU4831&&4832&&4834

时间:2014-05-26 19:39:24      阅读:378      评论:0      收藏:0      [点我收藏+]

标签:c   class   blog   code   http   a   

好久没打代码啦,今天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

HDU4831&&4832&&4834

标签:c   class   blog   code   http   a   

原文地址:http://www.cnblogs.com/chanme/p/3751898.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!