太气了。Atcoder unrated了。

这一场时间太不友好了。昨天下午一时兴起就去补了一发。题很好,学到好多东西。

Chain Reaction

题意:给一个矩阵,这个矩阵是稳定的当且仅当每一个元素都是稳定的。元素是稳定的当且仅当它的值严格小于它相邻有几个元素

思路:四个角的值就必须小于2,然后外圈的其他数的值就必须小于3,其他的就必须小于4。

#include <bits/stdc++.h>
using namespace std; inline int read() {
int x = , f = ; char ch = getchar();
while (ch < '' || ch > '') { if (ch == '-') f = -; ch = getchar(); }
while (ch >= '' && ch <= '') { x = x * + ch - ; ch = getchar(); }
return x * f;
} const int N = ;
int a[N][N]; int main() {
int T = read();
while (T--) {
int r = read(), c = read();
bool ans = false;
for (int i = ; i <= r; i++) {
for (int j = ; j <= c; j++) {
a[i][j] = read();
if (i == ) {
if (i == j || j == c) {
if (a[i][j] >= ) ans = true;
} else {
if (a[i][j] >= ) ans = true;
}
} else if (i == r) {
if ( == j || j == c) {
if (a[i][j] >= ) ans = true;
} else {
if (a[i][j] >= ) ans = true;
}
} else if (j == || j == c) {
if (a[i][j] >= ) ans = true;
} else {
if (a[i][j] == ) ans = true;
}
}
}
if (ans) puts("Unstable");
else puts("Stable");
}
}

Recover the Sequence

题意:一个等差数列,其中一个数被改了,要求原数列。

思路:四项肯定可以出一个等差数列,只看前四项就ok了。

#include <bits/stdc++.h>
using namespace std; inline int read() {
int x = , f = ; char ch = getchar();
while (ch < '' || ch > '') { if (ch == '-') f = -; ch = getchar(); }
while (ch >= '' && ch <= '') { x = x * + ch - ; ch = getchar(); }
return x * f;
} const int N = 1e5 + ;
int a[N], b[N]; int main() {
int T = read();
while (T--) {
int n = read();
for (int i = ; i <= n; i++) a[i] = read();
if (a[] - a[] == a[] - a[]) {
int d = a[] - a[];
for (int i = ; i <= n; i++) {
a[i] = a[i-] + d;
}
} else if (a[] - a[] == a[] - a[]) {
int d = a[] - a[];
for (int i = n - ; i > ; i--) {
a[i] = a[i+] - d;
}
} else {
int d = (a[] - a[]) / ;
for (int i = ; i <= n; i++) {
a[i] = a[i - ] + d;
}
}
for (int i = ; i <= n; i++) { if (i - ) putchar(' '); printf("%d", a[i]); }
puts("");
}
return ;
}

Misha and Nice Sets

题意:给一个区间$l,r$和一个数$g$,要求这个区间内最多有几个数的GCD刚好为$g$

思路:容斥求,WA了好几发,原因是。当容斥出来结果只有1个时,$g$必须在$l,r$之间,不然这一个数的最大因子是自己而不是$g$。

题目描述也是The greatest positive integer which divides each element of the set is exactly $g$,一个数的greatest positive integer which divide it是它本身。

#include <bits/stdc++.h>
#define ll long long
using namespace std; inline ll readl() {
ll x = , f = ; char ch = getchar();
while (ch < '' || ch > '') { if (ch == '-') f = -; ch = getchar(); }
while (ch >= '' && ch <= '') { x = x * + ch - ; ch = getchar(); }
return x * f;
} int main() {
ll T = readl();
while (T--) {
ll l = readl(), r = readl(), g = readl();
ll ans = r / g - l / g + (l % g == );
if (ans == ) {
if (g < l || g > r) ans = ;
}
printf("%lld\n", ans);
}
return ;
}

Searching for a Biclique

题意:给一个有向图,问能不能删边删点使他们成为一个二分图 一边点数为2,一边点数为$k$

思路:暴力求。不知道为啥不会T。咱也不知道,咱也不敢问。

#include <bits/stdc++.h>
using namespace std; inline int read() {
int x = , f = ; char ch = getchar();
while (ch < '' || ch > '') { if (ch == '-') f = -; ch = getchar(); }
while (ch >= '' && ch <= '') { x = x * + ch - ; ch = getchar(); }
return x * f;
} const int N = 2e3 + ;
vector<int> G[N]; int main() {
int n = read(), m = read(), k = read();
for (int i = ; i < m; i++) {
int u = read(), v = read();
G[u].emplace_back(v);
G[v].emplace_back(u);
}
for (int i = ; i <= n; i++) sort(G[i].begin(), G[i].end());
for (int i = ; i <= n; i++) {
for (int j = i + ; j <= n; j++) {
int p1 = , p2 = ;
int ans = ;
int sz1 = G[i].size(), sz2 = G[j].size();
while (p1 < sz1 && p2 < sz2) {
if (G[i][p1] == G[j][p2]) {
p1++;p2++; ans++;
} else if (G[i][p1] < G[j][p2]) {
p1++;
} else p2++;
}
if (ans >= k) { puts("YES"); return ;}
}
}
puts("NO");
return ;
}

看了题解的解法。复杂度就比较科学了。$O\left( n^{2}k\right)$

#include <bits/stdc++.h>
using namespace std; inline int read() {
int x = , f = ; char ch = getchar();
while (ch < '' || ch > '') { if (ch == '-') f = -; ch = getchar(); }
while (ch >= '' && ch <= '') { x = x * + ch - ; ch = getchar(); }
return x * f;
} const int N = 2e3 + ;
vector<int> G[N];
int cnt[N][N]; int main() {
int n = read(), m = read(), k = read();
for (int i = ; i < m; i++) {
int u = read(), v = read();
G[u].emplace_back(v);
G[v].emplace_back(u);
}
bool ans = false;
for (int i = ; i <= n; i++) {
if (ans) break;
for (auto x: G[i]) {
if (ans) break;
for (auto y: G[i]) {
if (x < y) {
cnt[x][y]++;
cnt[y][x]++;
}
if (cnt[x][y] >= k) {
ans = true;
break;
}
}
}
}
if (ans) puts("YES");
else puts("NO");
return ;
}

Expected Xor

题意:给n个物品,每个物品有值$b_{i}$和选中概率$p_{i}$,求异或和的期望

思路:emmmm概率题本来就不太会再加上异或emmmmm

按位考虑每一个数,因为异或是两个相同就变成0了。那么能对期望做出贡献的时候就是二选一的时候

pro表示在当前位,当前数能对期望做出贡献的概率。

到下一个数的时候就是$pro\ast \left( 1-p_{i}\right) + p_{i}\ast \left( 1-pro\right)$

最后乘上(1 << k) 就行了 k表示当前位

#include <bits/stdc++.h>
using namespace std; inline int read() {
int x = , f = ; char ch = getchar();
while (ch < '' || ch > '') { if (ch == '-') f = -; ch = getchar(); }
while (ch >= '' && ch <= '') { x = x * + ch - ; ch = getchar(); }
return x * f;
} const int N = 1e5 + ;
int b[N], n;
double p[N]; int main() {
int T; scanf("%d", &T);
while (T--) {
scanf("%d", &n);
for (int i = ; i < n; i++) scanf("%d", &b[i]);
for (int i = ; i < n; i++) scanf("%lf", &p[i]);
long double ans = ;
for (int bit = ; bit < ; bit++) {
long double pro = ;
for (int i = ; i < n; i++) {
if ((b[i] >> bit) & ) {
pro = ( - pro) * (long double)p[i] + pro * ( - (long double)p[i]);
}
}
ans += ( << bit) * pro;
}
printf("%.7Lf\n", ans);
}
return ;
}

Bitsetbaba and Power Grid

题意:有节点0到$2^{k} - 1$,给一个序列$m_{i}$ ,所有点对$u,v$ $u\oplus v = m_{i}$的之间连边,问最后有多少个连通块

思路:推了半天结论也没推明白。看题解才明白是高斯消元。

对于一个节点$u$,它能到达的点是这个序列的数,任意组合,异或之后的值的个数(加上一个0)

本来是只能异或这个序列里面的一个数,但是由于别的数也会异或,就会连通了。

比如两个节点1 和 2

$m_{1} = 1$ $m_{2} = 2$

1和$m_{1}$异或后是0 和$m_{2}$异或后是3 2和$m_{1}$异或后是3

本来只异或一个值的话,1和2看起来是不连通的

但就是会间接相连 所以就是xjb组合着去异或

然后答案就是看这个序列能异或出多少种值来。

把它们按二进制排成一个矩阵。

求出这个矩阵的秩$r$

答案就是$2^{k - r}$

解释:把矩阵通过异或运算变成行阶梯型之后,秩为$r$,前$r$行的线性组合得到的结果必是不一样了

然后取和不取种类数就是$2^{r}$种

#include <bits/stdc++.h>
using namespace std; inline int read() {
int x = , f = ; char ch = getchar();
while (ch < '' || ch > '') { if (ch == '-') f = -; ch = getchar(); }
while (ch >= '' && ch <= '') { x = x * + ch - ; ch = getchar(); }
return x * f;
} const int N = 1e5 + ;
int a[N];
int bin[N]; int main() {
int T = read();
while (T--) {
memset(bin, , sizeof(bin));
int k = read(), m = read();
for (int i = ; i < m; i++) {
int x = read();
for (int j = ; j < ; j++) {
if ((<<j) & x) {
if (!bin[j]) {
bin[j] = x;
k--;
break;
}
x ^= bin[j];
}
}
}
cout << ( << k) << '\n';
}
return ;
}

Nearest Color

题意:一棵树,刚开始只有根1和颜色$c$,给$Q$次询问,询问有两种,第一种是给节点$u$加上一个儿子(编号为当前节点数+1),颜色染成$c$,第二种询问颜色为$c$的节点中,和$u$最近的距离是多少。

思路:直接写了发暴力找+倍增LCA,T了。看了题解才发现有trick。

把颜色分为大和小。以300次为界限。

出现次数小于300的就可以直接暴力+LCA

大于300的把颜色为$c$的节点$u$ $dis[c][u] = 0$并且对这些节点进行bfs

bfs过程中若dis为INF的话就可以更新成$dis[c][u] + 1$

#include <bits/stdc++.h>
using namespace std; inline int read() {
int x = , f = ; char ch = getchar();
while (ch < '' || ch > '') { if (ch == '-') f = -; ch = getchar(); }
while (ch >= '' && ch <= '') { x = x * + ch - ; ch = getchar(); }
return x * f;
} const int N = 2e5 + ;
const int RT = ;
const int INF = 0x3f3f3f3f;
vector<int> group[N];
vector<int> rem[N];
vector<int> big;
vector<int> adj[N];
vector<int> dis[N];
int fa[N], lca[N][], n, dep[N], q, col[N]; void recalc(int c) {
if (dis[c].empty()) big.emplace_back(c);
dis[c].assign(n + , N);
queue<int> que;
for (int u: group[c]) {
dis[c][u] = ;
que.push(u);
}
while (!que.empty()) {
int u = que.front(); que.pop();
for (int v: adj[u]) {
if (dis[c][v] == N) {
dis[c][v] = dis[c][u] + ;
que.push(v);
}
}
}
rem[c].clear();
} void add(int u, int c) {
n++;
col[n] = c;
lca[n][] = fa[n] = u;
adj[n].emplace_back(u);
adj[u].emplace_back(n);
dep[n] = dep[u] + ;
for (int i = ; i <= ; i++) lca[n][i] = lca[lca[n][i-]][i-];
for (int cc: big) dis[cc].emplace_back(dis[cc][u] + );
group[c].emplace_back(n);
rem[c].emplace_back(n);
if (rem[c].size() >= RT) recalc(c);
} int Lca(int u, int v) {
if (dep[u] < dep[v]) swap(u, v);
int f = dep[u] - dep[v];
for (int i = ; i <= ; i++) {
if (f & ( << i)) {
u = lca[u][i];
}
}
if (u == v) return v;
for (int i = ; i >= ; i--) {
if (lca[u][i] != lca[v][i]) {
u = lca[u][i];
v = lca[v][i];
}
}
return lca[u][];
} int distance(int u, int v) {
return dep[u] + dep[v] - * dep[Lca(u, v)];
} int query(int u, int c) {
int ans = dis[c].size() ? dis[c][u] : N;
for (int v: rem[c]) ans = min(ans, distance(u, v));
if (ans == N) ans = -;
return ans;
} void init() {
for (int i = ; i < N; i++) {
adj[i].clear();
group[i].clear();
dis[i].clear();
rem[i].clear();
}
big.clear();
n = ;
} int main() {
int T = read();
while (T--) {
init();
q = read();int c = read();
group[c].emplace_back();
rem[c].emplace_back();
dep[] = ; fa[] = ;
int a = -;
while (q--) {
char s[];
scanf("%s", s);
int u = read(); c = read();
u = u ^ (a + ); c = c ^ (a + );
if (s[] == '+') add(u, c);
else printf("%d\n", a = query(u, c));
}
}
return ;
}

还是太菜了呀...

May Cook-Off 2019 解题报告的更多相关文章

  1. 【LeetCode】236. Lowest Common Ancestor of a Binary Tree 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  2. 【LeetCode】684. Redundant Connection 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 并查集 日期 题目地址:https://leetco ...

  3. 【LeetCode】817. Linked List Components 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  4. 【LeetCode】90. Subsets II 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 回溯法 日期 题目地址:https://leet ...

  5. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

  6. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  7. BZOJ 1051 最受欢迎的牛 解题报告

    题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[S ...

  8. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

  9. 习题:codevs 1035 火车停留解题报告

    本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...

随机推荐

  1. [转帖]rename(Perl语言版本) 详解

    rename(Perl语言版本) 详解 2019-03-19 22:51:23 wayne17 阅读数 464更多 分类专栏: Ubuntu之路   版权声明:本文为博主原创文章,遵循CC 4.0 B ...

  2. POJ 1251 Jungle Roads - C语言 - Kruskal算法

    Description The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid ...

  3. C语言 小球撞击反弹

    计算法(略) #include <stdio.h> #include <stdlib.h> int main() { int x, y, a, resu; scanf(&quo ...

  4. Python知识点总结篇(二)

    列表 列表:一个值,包含多个字构成的序列,用[ ]括起来,[]是一个空列表,不包含任何值,类似于空字符串,负数下标表示从后边开始,-1表示列表最后一个下标,它是一种可变的数据类型,值可以添加.删除或改 ...

  5. Go基础编程实践(五)—— 错误和日志

    自定义错误类型 Go中可以使用errors.New()创建错误信息,也可以通过创建自定义错误类型来满足需求.error是一个接口类型,所有实现该接口的类型都可以当作一个错误类型. // error类型 ...

  6. LOJ2461 完美的队列 分块

    传送门 如果对于每一个操作\(i\)找到这个操作中所有的数都被pop掉的时间\(ed_i\),那么剩下就直接差分覆盖一下就可以了. 那么考虑如何求出\(ed_i\).发现似乎并没有什么数据结构能够维护 ...

  7. .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?

    原文:.NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用? 都知道可以在任务管理器中查看进程的 CPU 和内存占用,那么如何通过 .NET 编写代码的方式来获取到 ...

  8. 2019 智联招聘java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.智联等公司offer,岗位是Java后端开发,因为发展原因最终选择去了智联,入职一年时间了,之前面试了很多家公 ...

  9. git安装用法和常用命令

    目录 git 下载 安装 git 工作中常用命令 Git常用命令汇总以及其它相关操作 或者 常出错误: 常用修改: 题外话(相关概念) git 下载 安装 1.下载Git,官网地址:https://g ...

  10. restframework中根据请求的类型修改序列化类

    只要在视图中重写get_serializer_class方法就可以,用if对请求的类型进行判断 def get_serializer_class(self): if self.action == &q ...