Codeforces Round #316 (Div. 2) 简单题解

简单小结:
A题
先找出每个城市中得票最高的
然后再在以上求出的那帮人中出一个得票(一个城市只算一票)中最高的

 1 /***********************************
 2 *                                  *
 3 *    Auther Rhapsody               *
 4 *    E-mail [email protected]    *
 5 *                                  *
 6 ***********************************/
 7 #include <set>
 8 #include <map>
 9 #include <cmath>
10 #include <deque>
11 #include <queue>
12 #include <vector>
13 #include <cstdio>
14 #include <cstdlib>
15 #include <cstring>
16 #include <iostream>
17 #include <algorithm>
18
19 #define MP make_pair
20 #define PB push_back
21
22 using namespace std;
23
24 typedef long long LL;
25 typedef pair<int, int> PII;
26
27 const int N = 1e2 + 7;
28 const int INF = 0x3f3f3f3f;
29 const int MOD = 1e9 + 7;
30
31 int a[N][N];
32
33 int cnt[N];
34
35 int main(void) {
36     int n, m;
37     scanf("%d%d", &n, &m);
38     for (int i = 1; i <= m; ++i) {
39         for (int j = 1; j <= n; ++j) {
40             scanf("%d", &a[i][j]);
41         }
42     }
43     for (int i = 1; i <= m; ++i) {
44         int k = 1;
45         for (int j = 2; j <= n; ++j)
46             if (a[i][j] > a[i][k])
47                 k = j;
48         a[i][0] = k;
49     }
50     for (int i = 1; i <= m; ++i) {
51         ++cnt[a[i][0]];
52     }
53     int Ans = 1;
54     for (int i = 1; i <= n; ++i)
55         if (cnt[Ans] < cnt[i])
56             Ans = i;
57     cout << Ans << endl;
58     return 0;
59 }

B题
我们可以画一个图,画一个坐标轴
我们很显然的可以看出,a=c-1或者a=c+1两者必有一个是最佳答案

 1 /***********************************
 2 *                                  *
 3 *    Auther Rhapsody               *
 4 *    E-mail [email protected]    *
 5 *                                  *
 6 ***********************************/
 7 #include <set>
 8 #include <map>
 9 #include <cmath>
10 #include <deque>
11 #include <queue>
12 #include <vector>
13 #include <cstdio>
14 #include <cstdlib>
15 #include <cstring>
16 #include <iostream>
17 #include <algorithm>
18
19 #define MP make_pair
20 #define PB push_back
21
22 using namespace std;
23
24 typedef long long LL;
25 typedef pair<int, int> PII;
26
27 const int N = 1e5 + 7;
28 const int INF = 0x3f3f3f3f;
29 const int MOD = 1e9 + 7;
30
31 int main(void) {
32     int n, m;
33     scanf("%d%d", &n, &m);
34     int l = m - 1, r = m + 1;
35     if (n == 1) {
36         cout << 1 << endl;
37         return 0;
38     }
39     if (l == 0) {
40         cout << r << endl;
41         return 0;
42     }
43     if (r > n) {
44         cout << l << endl;
45         return 0;
46     }
47     if (l >= n - m)
48         cout << l << endl;
49     else
50         cout << r << endl;
51     return 0;
52 }

C题
首先对于初始的那个串,我们可以通过一次扫描把最初始的答案求出
具体做法就是找到一个长度为l的连续的“...”串,那么答案就+(l-1)
我们可以通过分类讨论
先讨论用‘.’替换‘.’:并没有什么卵用
同理用字母替换字母:也没有什么卵用
用‘.’替换字母:如果左边也是‘.’那么我们统计的那个答案就可以+1了,同理右边如果也是‘.’那么我们就答案+1
用字母替换‘.’:如果旁边有一个‘.’那么答案就-1
通过以上讨论进行及时的计算

 1 /***********************************
 2 *                                  *
 3 *    Auther Rhapsody               *
 4 *    E-mail [email protected]    *
 5 *                                  *
 6 ***********************************/
 7 #include <set>
 8 #include <map>
 9 #include <cmath>
10 #include <deque>
11 #include <queue>
12 #include <vector>
13 #include <cstdio>
14 #include <cstdlib>
15 #include <cstring>
16 #include <iostream>
17 #include <algorithm>
18
19 #define MP make_pair
20 #define PB push_back
21
22 using namespace std;
23
24 typedef long long LL;
25 typedef pair<int, int> PII;
26
27 const int N = 3e5 + 7;
28 const int INF = 0x3f3f3f3f;
29 const int MOD = 1e9 + 7;
30
31 bool c[N];
32
33 char s[N];
34
35 int main(void) {
36     int n, m;
37     scanf("%d%d", &n, &m);
38     scanf("%s", s + 1);
39     int Ans = 0;
40     for (int i = 1; i <= n; ++i) {
41         if (s[i] == ‘.‘)
42             c[i] = true;
43         else
44             c[i] = false;
45         if (s[i] == ‘.‘ && s[i - 1] == ‘.‘)
46             ++Ans;
47     }
48     //cout << Ans << endl;
49     while (m--) {
50         int x;
51         char ch;
52         scanf("%d %c", &x, &ch);
53         if (ch == ‘.‘ && !c[x]) {
54             c[x] = true;
55             if (x > 1 && c[x - 1])
56                 ++Ans;
57             if (x < n && c[x + 1])
58                 ++Ans;
59         }
60         if (ch != ‘.‘ && c[x]) {
61             c[x] = false;
62             if (x > 1 && c[x - 1])
63                 --Ans;
64             if (x < n && c[x + 1])
65                 --Ans;
66         }
67         printf("%d\n", Ans);
68     }
69     return 0;
70 }

D题
感觉题出的真心很不错
题目大意就是,给你一棵有根树(节点数量500000级别),每个节点上面都有一个字母,然后给你一定询问(500000级别)
每次询问<v, h>就是问你v这个节点的子树中深度为h的所有节点上的字母是否能够组成为一个回文串
首先字母只有小写的26个字母
这一堆字母能不能构成回文串的因素就是这26个字母的出现次数最多只能有一个是偶数
如果是问一个字符串,询问某个连续的子串如果打乱顺序的话是否能够构成一个回文串
那么我们只需要开一个sum记录这个字符串的每个字母出现次数的前缀和即可
但是问题是这个是在一个树上了,那么我们可以利用dfs序来解决这个问题,把树转化为链,对于深度问题,我们只需要把每个深度的点放在一起,然后用二分查找的方法就可以解决这个问题

  1 /***********************************
  2 *                                  *
  3 *    Auther Rhapsody               *
  4 *    E-mail [email protected]    *
  5 *                                  *
  6 ***********************************/
  7 #include <set>
  8 #include <map>
  9 #include <cmath>
 10 #include <deque>
 11 #include <queue>
 12 #include <vector>
 13 #include <cstdio>
 14 #include <cstdlib>
 15 #include <cstring>
 16 #include <iostream>
 17 #include <algorithm>
 18
 19 #define MP make_pair
 20 #define PB push_back
 21
 22 using namespace std;
 23
 24 typedef long long LL;
 25 typedef pair<int, int> PII;
 26
 27 const int N = 5e5 + 7;
 28 const int INF = 0x3f3f3f3f;
 29 const int MOD = 1e9 + 7;
 30
 31 vector <int> e[N];
 32
 33 vector <PII> head[N];
 34
 35 char s[N];
 36
 37 int in[N], out[N], pos;
 38
 39 void dfs(int u, int d) {
 40     //printf("Dfs : %d %d\n", u, d);
 41     in[u] = ++pos;
 42     for (int i = 0; i < e[u].size(); ++i) {
 43         int v = e[u][i];
 44         dfs(v, d + 1);
 45     }
 46     head[d].PB(MP(u, 0));
 47     out[u] = pos;
 48 }
 49
 50 void deal(vector <PII> &data) {
 51     //printf("Deal : \n");
 52     for (int i = 1; i < data.size(); ++i) {
 53         data[i].second = data[i - 1].second;
 54         data[i].second ^= 1 << (s[data[i].first] - ‘a‘);
 55         //printf("%d %d\n", data[i].first, data[i].second);
 56     }
 57 }
 58
 59 int find(int k, vector <PII> &data) {
 60     //printf("Aim is %d\n", k);
 61     int l = 0, r = data.size() - 1;
 62     while (l < r) {
 63         int mid = ((l + r) >> 1) + 1;
 64         if (in[data[mid].first] <= k)
 65             l = mid;
 66         else
 67             r = mid - 1;
 68     }
 69     return l;
 70 }
 71
 72 bool judge(int x) {
 73     return (x & (x - 1)) == 0;
 74 }
 75
 76 bool ask(int u, vector <PII> &data) {
 77     //printf("Ask : %d\n", u);
 78     int r = find(out[u], data), l = find(in[u] - 1, data);
 79     //printf("Get %d %d\n", l, r);
 80     //printf("R = %d\n", data[r].first);
 81     if (in[u] > in[data[r].first] || out[u] < in[data[r].first]) return true;
 82     return judge(data[l].second ^ data[r].second);
 83 }
 84
 85 int main(void) {
 86     int n, Q;
 87     scanf("%d%d", &n, &Q);
 88     for (int i = 2; i <= n; ++i) {
 89         int u;
 90         scanf("%d", &u);
 91         e[u].PB(i);
 92     }
 93     for (int i = 1; i <= n; ++i)
 94         head[i].PB(MP(0, 0));
 95     dfs(1, 1);
 96     scanf("%s", s + 1);
 97     for (int i = 1; i <= n; ++i) {
 98         //printf("Deal : %d\n", i);
 99         deal(head[i]);
100     }
101     while (Q--) {
102         int v, h;
103         scanf("%d%d", &v, &h);
104         //printf("Ask : %d %d\n", v, h);
105         if (ask(v, head[h]))
106             puts("Yes");
107         else
108             puts("No");
109     }
110     return 0;
111 }

E题
DP,对角线优化+滚动数组
何为对角线优化?
如我我们想到了动态规划,我们最开始可以有这样的想法:f[i][j][k][l]
代表开头在i, j结尾再k, l的位置的方案数
我们仔细发现,i + j与k + l有什么关系呢?
我们可以画一画矩阵的对角线来理解理解
i + j + k + l == n + m + 2
所以带上你的滚动数组AC吧

 1 /***********************************
 2 *                                  *
 3 *    Auther Rhapsody               *
 4 *    E-mail [email protected]    *
 5 *                                  *
 6 ***********************************/
 7 #include <set>
 8 #include <map>
 9 #include <cmath>
10 #include <deque>
11 #include <queue>
12 #include <vector>
13 #include <cstdio>
14 #include <cstdlib>
15 #include <cstring>
16 #include <iostream>
17 #include <algorithm>
18
19 #define MP make_pair
20 #define PB push_back
21
22 using namespace std;
23
24 typedef long long LL;
25 typedef pair<int, int> PII;
26
27 const int N = 512;
28 const int INF = 0x3f3f3f3f;
29 const int MOD = 1e9 + 7;
30
31 char s[N][N];
32
33 int f[2][N][N];
34
35 int main(void) {
36     int n, m;
37     scanf("%d%d", &n, &m);
38     for (int i = 1; i <= n; ++i) {
39         scanf("%s", s[i] + 1);
40     }
41     int h = n + m + 2;
42     if ((n + m) & 1) {
43         int k = h >> 1;
44         for (int i = 1; i <= n; ++i) {
45             int j = k - i;
46             if (j <= 0 || j > m) continue;
47             for (int u = 1; u <= n; ++u) {
48                 int v = h - k - u;
49                 if (v <= 0 || v > m) continue;
50                 if (s[i][j] == s[u][v] && abs(i - u) + abs(j - v) == 1)
51                     f[k & 1][i][u] = 1;
52             }
53         }
54     } else {
55         int k = h >> 1;
56         for (int i = 1; i <= n; ++i)
57             f[k & 1][i][i] = 1;
58     }
59     for (int k = h / 2 - 1; k >= 2; --k) {
60         int op = k & 1;
61         for (int i = 1; i <= n; ++i) {
62             int j = k - i;
63             if (j <= 0 || j > m) continue;
64             for (int u = 1; u <= n; ++u) {
65                 int v = h - k - u;
66                 if (v <= 0 || v > m) continue;
67                 if (s[i][j] != s[u][v]) {
68                     f[op][i][u] = 0;
69                     continue;
70                 }
71                 f[op][i][u] = (f[op ^ 1][i][u] + f[op ^ 1][i + 1][u]) % MOD + (f[op ^ 1][i][u - 1] + f[op ^ 1][i + 1][u - 1]) % MOD;
72                 f[op][i][u] %= MOD;
73             }
74         }
75     }
76     printf("%d\n", f[0][1][n]);
77     return 0;
78 }
时间: 2024-11-07 09:31:53

Codeforces Round #316 (Div. 2) 简单题解的相关文章

Codeforces Round #FF (Div. 1)简单题解

A .DZY Loves Sequences pro:给定长度为N的序列,你最多可以改变一个数的值,问最长严格上升子序列长度. N<1e5. sol:分几种情况,一种的不改变: 一种是改变,然后接上一个: 一个是改变中间一个,接上两段,而且满足a[mid-1]<a[mid]<a[mid+1] #include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;i++) cons

# Codeforces Round #529(Div.3)个人题解

Codeforces Round #529(Div.3)个人题解 前言: 闲来无事补了前天的cf,想着最近刷题有点点怠惰,就直接一场cf一场cf的刷算了,以后的题解也都会以每场的形式写出来 A. Repeating Cipher 传送门 题意:第一个字母写一次,第二个字母写两次,依次递推,求原字符串是什么 题解:1.2.3.4,非常明显的d=1的等差数列,所以预处理一个等差数列直接取等差数列的每一项即可 代码: #include<bits/stdc++.h> using namespace s

Codeforces Round #531 (Div. 3) ABCDE题解

Codeforces Round #531 (Div. 3) 题目总链接:https://codeforces.com/contest/1102 A. Integer Sequence Dividing 题意: 给一个数n,然后要求你把1,2.....n分为两个集合,使得两个集合里面元素的和的差的绝对值最小. 题解: 分析可以发现,当n%4==0 或者 n%3==0,答案为0:其余答案为1.之后输出一下就好了. 代码如下: #include <bits/stdc++.h> using name

Codeforces Round #540 (Div. 3) 部分题解

Codeforces Round #540 (Div. 3) 题目链接:https://codeforces.com/contest/1118 题目太多啦,解释题意都花很多时间...还有事情要做,就选一些题来写吧. B. Tanya and Candies 题意: 在n个数中任意删去一个,如果这个数被删去后,剩余数的奇数和以及偶数和相等,那么就定义这个数为"好数".现在问这n个数中有多少个“好数”. 题解: 预处理出奇数前缀和.偶数前缀和,删去一个数后所有的奇数位置和 就为前面的奇数和

Codeforces Round #632 (Div. 2) 部分题解

目录 Codeforces Round #632 (Div. 2) A. Little Artem B. Kind Anton C. Eugene and an array D. Challenges in school №41 F. Kate and imperfection Codeforces Round #632 (Div. 2) A. Little Artem 题意:略. 分析:构造这样的图形: BWW...W BWW...W BBB...B #include <bits/stdc++

Codeforces Round #105 (Div. 2) (ABCDE题解)

比赛链接:http://codeforces.com/contest/148 比较简单的一场,最长的一题也才写了30行多一点 A. Insomnia cure time limit per test:2 seconds memory limit per test:256 megabytes ?One dragon. Two dragon. Three dragon?, - the princess was counting. She had trouble falling asleep, and

Codeforces Round #316 (Div. 2)C. Replacement(模拟)

传送门 Description Daniel has a string s, consisting of lowercase English letters and period signs (characters '.'). Let's define the operation of replacement as the following sequence of steps: find a substring ".." (two consecutive periods) in st

Codeforces Round #353 (Div. 2) ABCDE 题解 python

Problems # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring Painting standard input/output 1 s, 256 MB    x2519 C Money Transfers standard input/output 1 s, 256 MB    x724 D Tree Construction standard input/output 2

Codeforces Round #Pi (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/567 听说Round #Pi的意思是Round #314... A. Lineland Mail time limit per test:3 seconds memory limit per test:256 megabytes All cities of Lineland are located on the Ox coordinate axis. Thus, each city is associated with it