Codeforces Round #558 (Div. 2) 题解

A Eating Soup

分类讨论一下

\(m\) 个断点最多可以将环分成 \(m\) 段,而剩下 \(n-m\) 个点最多可以成为 \(n-m\) 段,取个 \(\min\) 即可

注意 \(m=0\) 时是一个环答案为 \(1\)

// Copyright lzt
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
#include<ctime>
using namespace std;
typedef long long ll;
typedef std::pair<int, int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef std::pair<long long, long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i, j, k) for (register int i = (int)(j); i <= (int)(k); i++)
#define rrep(i, j, k) for (register int i = (int)(j); i >= (int)(k); i--)
#define Debug(...) fprintf(stderr, __VA_ARGS__) inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0') {
x = 10 * x + ch - '0';
ch = getchar();
}
return x * f;
} int n, m; void work() {
n = read(), m = read();
if (m == 0) {
puts("1");
return;
}
int num = n - m;
printf("%d\n", min(num, m));
} int main() {
#ifdef LZT
freopen("in", "r", stdin);
#endif work(); #ifdef LZT
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
}

B Cat Party

倒着枚举长度并且维护每一个出现次数的个数

就是维护出现次数为 \(i\) 的数字有多少个

显然出现次数最多只能有两种(因为你只能修改 \(1\) 个数,也就只能修改一个出现次数)

然后就分类讨论一下最后删掉的是哪个即可

// Copyright lzt
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
#include<ctime>
using namespace std;
typedef long long ll;
typedef std::pair<int, int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef std::pair<long long, long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i, j, k) for (register int i = (int)(j); i <= (int)(k); i++)
#define rrep(i, j, k) for (register int i = (int)(j); i >= (int)(k); i--)
#define Debug(...) fprintf(stderr, __VA_ARGS__) inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0') {
x = 10 * x + ch - '0';
ch = getchar();
}
return x * f;
} const int maxn = 100100;
int n, cnt;
int a[maxn];
int b[maxn], num[maxn]; void work() {
n = read();
rep(i, 1, n) a[i] = read(), b[a[i]]++;
cnt = 0; set<int> col;
rep(i, 1, 100000) {
if (b[i]) {
num[b[i]]++;
cnt++, col.insert(b[i]);
}
}
rrep(i, n, 2) {
int nw = *col.begin();
if (num[nw] == 1 && col.size() > 1) nw = *(++col.begin());
if (col.size() <= 2) {
bool ok = 0;
if (col.size() == 1) {
int nw = *col.begin();
if (nw == 1 || num[nw] == 1) ok = 1;
else ok = 0;
} else {
int A = *col.begin(), B = *(++col.begin());
if (num[A] == 1 && A == 1) ok = 1;
else if (num[B] == 1 && B == 1) ok = 1;
else if (num[B] == 1 && B == A + 1) ok = 1;
else ok = 0;
}
if (ok) {
printf("%d\n", i);
return;
}
}
num[b[a[i]]]--;
if (num[b[a[i]]] == 0) col.erase(b[a[i]]);
b[a[i]]--;
if (b[a[i]]) {
num[b[a[i]]]++;
if (num[b[a[i]]] == 1) col.insert(b[a[i]]);
}
else cnt--;
}
puts("1");
} int main() {
#ifdef LZT
freopen("in", "r", stdin);
#endif work(); #ifdef LZT
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
}

C Power Transmission

答案显然是 \(calc(\text{不同的直线数量}) - \sum_{\text{斜率k}} calc(\text{斜率为k的直线数量})\)

其中 \(calc(x)=x*(x-1)/2\)

然后就枚举每两个点形成一条线,然后计数即可

// Copyright lzt
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
#include<ctime>
using namespace std;
typedef long long ll;
typedef std::pair<int, int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef std::pair<long long, long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i, j, k) for (register int i = (int)(j); i <= (int)(k); i++)
#define rrep(i, j, k) for (register int i = (int)(j); i >= (int)(k); i--)
#define Debug(...) fprintf(stderr, __VA_ARGS__) inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0') {
x = 10 * x + ch - '0';
ch = getchar();
}
return x * f;
} const int maxn = 1010;
int n;
pii p[maxn]; bool sm(double x, double y) {
return fabs(x - y) <= 1e-8;
} struct Line {
// Ax + By + C = 0
double A, B, C;
bool operator == (const Line &b) const {
return sm(A, b.A) && sm(B, b.B) && sm(C, b.C);
}
bool operator < (const Line &b) const {
if (sm(A, b.A)) {
if (sm(B, b.B)) return C < b.C;
return B < b.B;
}
return A < b.A;
}
void init() {
if (A == 0) C = C / B, B = 1;
else B = B / A, C = C / A, A = 1;
}
double calc() {
init();
if (A == 1) return B;
else return 1e30;
}
}; map<double, map<double, int> > M;
map<double, int> shit;
vector<Line> v; void work() {
n = read();
rep(i, 1, n) p[i].fi = read(), p[i].se = read();
ll num = 0;
rep(i, 1, n) rep(j, i + 1, n) {
Line nw;
nw.A = p[j].se - p[i].se;
nw.B = p[i].fi - p[j].fi;
nw.C = 0 - p[i].fi * nw.A - p[i].se * nw.B;
nw.init();
double k = nw.calc();
if (M[k][nw.C] == 0) {
M[k][nw.C] = 1;
num++; shit[k]++;
}
}
num = num * (num - 1) / 2;
for (map<double, int>::iterator it = shit.begin(); it != shit.end(); it++) {
int nw = it -> se;
num = num - nw * 1ll * (nw - 1) / 2;
}
printf("%lld\n", num);
} int main() {
#ifdef LZT
freopen("in", "r", stdin);
#endif work(); #ifdef LZT
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
}

D Mysterious Code

首先预处理 \(S[i][j]\) 和 \(T[i][j]\) 分别表示当前串的后缀与 \(s/t\) 的前缀的最长公共子串长度为 \(i\) (也就是只有最后 \(i\) 位有用,前面的都忽略),然后下一个位置填了字母 \(j\) 之后那个最长公共子串的长度(类似 \(kmp\) 的 \(fail\))

直接 \(dp\) \(f[i][j][k]\) 表示当前长度为 \(i\),在第一个串上的位置是 \(j\) ,在第二个串上的位置是 \(k\) 的最大 \(f(c',s)-f(c',t)\)

然后转移就暴力枚举一下下一个是啥

// Copyright lzt
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
#include<ctime>
using namespace std;
typedef long long ll;
typedef std::pair<int, int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef std::pair<long long, long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i, j, k) for (register int i = (int)(j); i <= (int)(k); i++)
#define rrep(i, j, k) for (register int i = (int)(j); i >= (int)(k); i--)
#define Debug(...) fprintf(stderr, __VA_ARGS__) inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0') {
x = 10 * x + ch - '0';
ch = getchar();
}
return x * f;
} const int maxn = 1010;
int n, m, len;
char s[maxn], t[maxn], c[maxn];
int f[maxn][55][55];
int S[55][26], T[55][26]; inline void getmx(int &x, int y) {
if (x < y) x = y;
} void work() {
scanf("%s", c + 1); len = strlen(c + 1);
scanf("%s", s + 1); n = strlen(s + 1);
rep(i, 0, n) rep(j, 0, 25) {
int len = i + 1;
rrep(k, min(len, n), 1) {
bool flag = true;
rep(_, 1, k - 1) if (s[i - k + _ + 1] != s[_]) {
flag = false; break;
}
if (s[k] - 'a' != j) flag = false;
if (flag) {
S[i][j] = k;
break;
}
}
// cout<<i<<' '<<j<<' '<<S[i][j]<<endl;
}
scanf("%s", t + 1); m = strlen(t + 1);
rep(i, 0, m) rep(j, 0, 25) {
int len = i + 1;
rrep(k, min(len, m), 1) {
bool flag = true;
rep(_, 1, k - 1) if (t[i - k + _ + 1] != t[_]) {
flag = false; break;
}
if (t[k] - 'a' != j) flag = false;
if (flag) {
T[i][j] = k;
break;
}
}
// cout<<i<<' '<<j<<' '<<T[i][j]<<endl;
}
rep(i, 0, len) rep(j, 0, n) rep(k, 0, m) f[i][j][k] = -1e9;
f[0][0][0] = 0;
rep(i, 0, len - 1) rep(j, 0, n) rep(k, 0, m) {
if (f[i][j][k] == -1e9) continue;
if (c[i + 1] != '*') {
int nw = c[i + 1] - 'a', pl = 0;
if (S[j][nw] == n) pl++;
if (T[k][nw] == m) pl--;
getmx(f[i + 1][S[j][nw]][T[k][nw]], f[i][j][k] + pl);
} else {
rep(nw, 0, 25) {
int pl = 0;
if (S[j][nw] == n) pl++;
if (T[k][nw] == m) pl--;
getmx(f[i + 1][S[j][nw]][T[k][nw]], f[i][j][k] + pl);
}
}
}
int ans = -1e9;
rep(j, 0, n) rep(k, 0, m) {
getmx(ans, f[len][j][k]);
}
printf("%d\n", ans);
} int main() {
#ifdef LZT
freopen("in", "r", stdin);
#endif work(); #ifdef LZT
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
}

E Magical Permutation

// Copyright lzt
#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
#include<ctime>
using namespace std;
typedef long long ll;
typedef std::pair<int, int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef std::pair<long long, long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i, j, k) for (register int i = (int)(j); i <= (int)(k); i++)
#define rrep(i, j, k) for (register int i = (int)(j); i >= (int)(k); i--)
#define Debug(...) fprintf(stderr, __VA_ARGS__) inline ll read() {
ll x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0') {
x = 10 * x + ch - '0';
ch = getchar();
}
return x * f;
} const int maxn = 200200;
int n, ans, pos;
int a[maxn], lb[20];
vector<int> vec;
bool vis[maxn << 2]; void add(int v) {
int tmp = v;
rrep(i, 20, 0) {
if (v & (1 << i)) {
if (lb[i]) v ^= lb[i];
else {
vec.pb(tmp);
lb[i] = v;
break;
}
}
}
} void dfs(int v, int num) {
printf("%d ", v); vis[v] = 1;
if (num == (1 << ans)) return;
rep(i, 0, vec.size() - 1) if (!vis[v ^ vec[i]]) {
dfs(v ^ vec[i], num + 1);
break;
}
} void work() {
n = read();
rep(i, 1, n) a[i] = read();
sort(a + 1, a + n + 1);
ans = 0, pos = 1;
rep(i, 1, 20) {
while (pos <= n && a[pos] < (1 << i)) {
add(a[pos]);
pos++;
}
bool flag = true;
rep(j, 0, i - 1) if (!lb[j]) flag = false;
if (flag) ans = i;
}
memset(lb, 0, sizeof(lb));
vec.clear();
rep(i, 1, n) {
if (a[i] < (1 << ans)) add(a[i]);
}
printf("%d\n", ans);
dfs(0, 1);
} int main() {
#ifdef LZT
freopen("in", "r", stdin);
#endif work(); #ifdef LZT
Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
}

Codeforces Round #558 (Div. 2)的更多相关文章

  1. Codeforces Round #558 (Div. 2)-Cat Party (Hard Edition)-(前缀和 + 模拟)

    http://codeforces.com/problemset/problem/1163/B2 题意:有n天,每天有一个颜色,截取前x天,随便抽掉一天,使剩下的各个颜色出现的次数相等. 解题,也可以 ...

  2. Codeforces Round #558 (Div. 2)B(SET,模拟)

    #include<bits/stdc++.h>using namespace std;int a[100007];int cnt[100007];int main(){    int n; ...

  3. Codeforces Round #558 (Div. 2)C(计算几何,排列组合,模拟)

    #include<bits/stdc++.h>using namespace std;typedef struct{ double k,b;}node;node k[1000007];bo ...

  4. Codeforces Round 558(Div 2)题解

    这场比赛没有打,后来和同学们一起开了场镜像打…… B是SB题结果WA了5发…… C是SB题结果差5min调出……虽然中间有个老师讲题吃掉了1h D是比较神仙的题(2200),但是做出来了?算是比较超常 ...

  5. Codeforces Round #366 (Div. 2) ABC

    Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...

  6. Codeforces Round #354 (Div. 2) ABCD

    Codeforces Round #354 (Div. 2) Problems     # Name     A Nicholas and Permutation standard input/out ...

  7. Codeforces Round #368 (Div. 2)

    直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...

  8. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  9. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

随机推荐

  1. 2048聚合版开源代码,cocos2d-js编写,基于CocosEditor开发工具,可运行Android,ios,html5等

    1. [代码][JavaScript]代码         /** * @GameName : * 2048 * * @DevelopTool: * Cocos2d-x Editor (CocosEd ...

  2. BZOJ 1607 [Usaco2008 Dec]Patting Heads 轻拍牛头:统计 + 筛法【调和级数】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1607 题意: 给你n个数,问你除a[i]之外,有多少个数是a[i]的约数. 题解: ans ...

  3. RQNOJ 624 运动鞋:dp

    题目链接:https://www.rqnoj.cn/problem/624 题意: 小明有奖学金啦!所以他要去买运动鞋. 总共有n款鞋,分别属于t个品牌. 每款鞋的价格为c[i],在小明心目中的价值为 ...

  4. java异常的原理以及应用

    父类Throwable 两个分支: error:合理的应用程序不应该出现的严重问题,可以无需声明便抛出,比如内存溢出. Exception:程序还能够克服和恢复的问题. 其中又分为系统异常和普通异常. ...

  5. 每天一个Linux命令(2):ls命令

    版权声明 更新:2017-04-26博主:LuckyAlan联系:liuwenvip163@163.com声明:吃水不忘挖井人,转载请注明出处! 1 文章介绍 本文介绍了Linux下命令ls. 2 开 ...

  6. BZOJ4278 [ONTAK2015]Tasowanie[后缀数组+贪心]

    题目 求两数组归并后的数组最小字典序排列. 嘛,可能本人在贪心这块还是太弱了(或者说什么都弱),如果不知道是字符串题估计也想不起来用sa. 显然看得出归并时字典序小的那个数组先往里面加,这就是要比较两 ...

  7. 【Python】数组排序

    1.numpy库:argsort() argsort函数返回的是数组值从小到大的索引值(升序排列) 一维: In [1]: import numpy as np In [2]: x = np.arra ...

  8. I/O:Unit1

    编程,从键盘读入学生成绩(0~100分),共15名学生,计算并显示总分.平均成绩.单的学生成绩 ; sum: avg: DATA1 SEGMENT STU DB ,,,,,,,,,,,,,, SUM ...

  9. AR/VR-VR:VR

    ylbtech-AR/VR-VR:VR 虚拟现实技术是一种可以创建和体验虚拟世界的计算机仿真系统,它利用计算机生成一种模拟环境,是一种多源信息融合的.交互式的三维动态视景和实体行为的系统仿真使用户沉浸 ...

  10. MODBUS ASCII和RTU两种模式的区别、优缺点

    转自:http://blog.sina.com.cn/s/blog_89f286ad0102uzju.html 下表是MODBUS ASCII协议和RTU协议的比较: 协议 开始标记 结束标记 校验 ...