HDU4831&&4832&&4834

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

时间: 2024-11-09 01:48:55

HDU4831&&4832&&4834的相关文章

hdu4831 Scenic Popularity(线段树)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4831 题目大概意思就是有多个风景区和休息区,每个风景区有热度,休息区的热度与最接近的分景区的热度相同,题目要求求出小于等于给定热度值的风景区和休息区的个数.显然如果直接暴力的话,复杂度为O(TKN),达到10^9次方数量级,复杂度过高,对于这种问答的题目,最一般的思路其实是线段树,线段树更改和查询的时间复杂度均为O(logn),所以如果用线段树的话,这道题目的复杂度为O(TKlogH),达到10^5

HDU 4832(DP+计数问题)

HDU 4832 Chess 思路:把行列的情况分别dp求出来,然后枚举行用几行,竖用几行,然后相乘累加起来就是答案 代码: #include <stdio.h> #include <string.h> #include <iostream> using namespace std; typedef long long ll; const ll MOD = 9999991; const int N = 1005; int t, n, m, k, x, y; ll dp1

hdu 4832 Chess(dp)

Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 193    Accepted Submission(s): 59 Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王"在棋盘上的走法遵循十字路线

HDU 4832 Chess (DP)

Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 24    Accepted Submission(s): 10 Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王"在棋盘上的走法遵循十字路线.

hdu 4832 百度之星初赛二B

把横的和竖的分开考虑 //#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<ma

HDU 4832 Chess 排列组合 DP

Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 351    Accepted Submission(s): 124 Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王"在棋盘 上的走法遵循十字

【BZOJ 4832 】 4832: [Lydsy2017年4月月赛]抵制克苏恩 (期望DP)

4832: [Lydsy2017年4月月赛]抵制克苏恩 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 275  Solved: 87 Description 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q 同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 30 点血量的英雄,并且可以用牌 召唤至多 7 个随从帮助玩家攻击对手,其中每个随从也拥有自己的血量和攻击力.小Q同学

bzoj 4832 抵制克苏恩

4832: [Lydsy2017年4月月赛]抵制克苏恩 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 441  Solved: 162[Submit][Status][Discuss] Description 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q 同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 30 点血量的英雄,并且可以用牌 召唤至多 7 个随从帮助玩家攻击

HDU 4832 组合计数dp

Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 509    Accepted Submission(s): 198 Problem Description 小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,"王"在棋盘上的走法遵循十字