太气了。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. LocalStack和Local对象实现栈的管理

    flask里面有两个重要的类Local和LocalStack 输入from flask import globals 左键+ctrl点globals进入源码,进去后找57行 flask只会实例化出这两 ...

  2. Golang修改json文件的两种方法

    第三方包 go get -u github.com/tidwall/sjson bytes, _ := ioutil.ReadFile(jsonFile) value1, _ := sjson.Set ...

  3. 【Linux】Ubuntu替换阿里源

    --------------------------------------------------------- 参考文章:https://www.jianshu.com/p/97c35d569aa ...

  4. BZOJ1060或洛谷1131 [ZJOI2007]时态同步

    BZOJ原题链接 洛谷原题链接 看上去就觉得是一道树形\(\mathtt{DP}\),不过到头来我发现我写了一个贪心.. 显然对越靠近根(记为\(r\))的边进行加权贡献越大,且同步的时间显然是从根到 ...

  5. Scala 系列(三)—— 流程控制语句

    一.条件表达式if Scala 中的 if/else 语法结构与 Java 中的一样,唯一不同的是,Scala 中的 if 表达式是有返回值的. object ScalaApp extends App ...

  6. AOP & 拦截器

    https://www.cnblogs.com/boywwj/p/7502185.html spring aop中@after-returning和@after,@afterThrowing,@Aro ...

  7. MongoDB和Java(3):Java操作MongoB

    最近花了一些时间学习了下MongoDB数据库,感觉还是比较全面系统的,涉及了软件安装.客户端操作.安全认证.副本集和分布式集群搭建,以及使用Spring Data连接MongoDB进行数据操作,收获很 ...

  8. 2019 讯飞java面试笔试题 (含面试题解析)

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

  9. Java之路---Day02

    2019-10-17-20:21:22 顺序结构: 概述:顺序执行,根据编写的顺序,从上到下执行语句 判断语句1-if: if语句第一种格式: if(关系表达式){ 语句体; } 执行流程: 1.首先 ...

  10. That IP address can't be assigned to.的问题

    That IP address can't be assigned to. 烦恼了很久,现在知道了,解决的办法如下 首先确定端口号是不是开放,阿里云的直接在控制台修改 其次 看看 你的地址是不是输入错 ...