自闭jpg. 就说说 PJ 吧。

TG炸的原因主要是因为PJ的炸裂以及T1……所以就直接分析根本原因了。

# 参考补题链接 #

# 推荐博客链接 #


0x00

考前一天晚上。

在LH巨佬家吃了饭,前往离HF大约1小时车程的NK边上的酒店。

到酒店收拾了一会儿,制订了个小计划,复习了不少板子。

像最短路,RMQ,LCA,EXGCD,euler啥的,都过了遍手。

当晚心态还是比较稳的,期待。

考试早上。

跟着大部队朦朦胧胧地到了NK门口。但好像一到门口就来精神了(?

然后在金牌讲师的带领下拍了OI生涯第一张比赛集体照。

接下来就在操场上等着进考场呗,期间遇到了几个外校的熟人,寒暄了几句。

进考场。

场地布置有点像ACM。

我还特别的注意到了以一种奇怪的方式折叠在天花板上的篮球框。

键盘,机器都还挺顺手的,不过座位刚好对着一条桌子腿,不是很舒服。

然后在裁判员宣读考试注意事项的时候,重新在脑袋里幻灯片了一下考试策略。(是的,我后面想起我考前还想过这玩意的


0x01

赛中。

T1一如既往的水。就直接每次暴力跑比n小的最大的二次幂即可。

5分钟打完调完过掉大样例跑去看T2。

T2就很迷惑了,想了半天只想出一个插排解法,心态直接就炸掉。但没办法,只能打完插排去看后面的题。一切炸的开始。

插排思路: 每次更新时二分找到之前的第i个位置,满足 a[i - 1] < x < a[i],将其插入,时间复杂度:你以为是 \(O(nlog_n)\) ?hhhhhh其实是 \(O(n^2)\)

T3感觉不可做,放掉,看T4。

T4第一眼好熟悉!马上反应是道dp,乱推了一堆通过单个二维转移的方程,没解出来。左看右看,考虑是不是最短路,结果直接随手把自己hack掉。最后打了个爆搜走人(我当时降智到直接没考虑记忆化。

再回去看T3,以为正解就是个暴力,后缀表达式乱搞交掉。

又跑去看T4,慌得要死,一直推到结束都没推出来。

最后五分钟T1刷了一个样例,感觉自己打错了,但其实是对的。于是魔改了一下,导致一中午都在担心自己好像没保存。

赛后。

一出考场就想起T4第二维两个循环转移。

一出考场就想起T2直接桶。。。(LH打树状数组过了,JC打对顶堆过了。

我谔谔,这次主要是心态炸锅了,太紧张了,导致一些白菜题没有切掉。

当然,后来反思也有考试策略有问题的成分。

估分:\(100\) \(+\) \(85\) \(+\) \(30\) \(+\) \(20\) \(=\) \(235\)。

实际能力极限:\(100\) \(+\) \(100\) \(+\) \(30\) \(+\) \(100\) \(=\) \(330\)。

以后做题还是应该再踏实一点,多做做思维题。

唉,好好复习NOIP吧。


0x02

题解部分

T1: (不再赘述。

#include <cstdio>

const int MAXN = 1e6 + 5;
int ans[MAXN], len = 0; int main() {
int n;
scanf ("%d", &n);
while(n) {
if(n == 1) {
printf("-1");
return 0;
}
long long t = 1;
while(t <= n)
t <<= 1;
if(t > n)
t >>= 1;
n -= t;
ans[++len] = t;
}
for(int i = 1; i < len; i++)
printf("%d ", ans[i]);
printf("%d", ans[len]);
return 0;
}

T2: (数据只到600?那毋庸置疑是个桶a。不要像我那样没看到600,导致只打了插排。

每次更新新的分数的时候,累加相对应的桶。

然后每次查找的时候,从大往小暴力找,找到分数线的位置直接输出即可。

时间复杂度:\(O(600n)\)

#include <cstdio>

inline int Max(int x, int y) {return x > y ? x : y;}
const int MAXN = 1e5 + 5;
const int MAXT = 605;
int a[MAXN], t[MAXT]; int main() {
int n, w;
scanf ("%d %d", &n, &w);
for(int i = 1; i <= n; i++) {
int x;
scanf ("%d", &x);
t[x]++;
int index = Max(1, i * w / 100), tot = 0, res = 0;
for(int j = 600; j >= 0; j--) {
tot += t[j];
if(tot >= index) {
res = j;
break;
}
}
printf("%d ", res);
}
return 0;
}

T3:(其实也不难想哦 可我还是不会

暴力就不提了吧。栈乱搞有30pt。个人认为这应该是最难的一道了。

至于正解,我们引入一个奇怪的字符树。

首先,你会发现整个表达式的取值只和一些特定的值有关,比如:

1 | (……) = 1;

0 & (……) = 0.

那么根据这个思路我们就可以考虑建树了嘛。实现看码。

时间复杂度:或许是 \(O(n + q)\) 吧。

#include <cstdio>
#include <stack>
#include <cstring>
using namespace std; const int MAXN = 1e6 + 5;
int a[MAXN], len = 0;
// a[]一组多用,下标 1 ~ n 为数集,n ~ 为符号集。
int cnt[MAXN], t[MAXN][2], Index = 0, n = 0;
// cnt-方便输入的数组,t 树,index 输入建树的下标。
bool vis[MAXN], q[MAXN];
// vis 表示这个数是否会决定表达式的答案,q 表示取反标记。
// vis 中,true 表示它不是决定性的,false 表示是决定性的。
char s[MAXN]; int dfs(int u, int f) {
// 在建树过程中顺便算出初始表达式的值。
// u 表示遍历,f 表示遍历时的取反标记。
a[u] ^= f; // 取反。
if(u <= n)
return a[u]; // 如果属于数集直接返回。
a[u] ^= f;
// 如果不属于数集,先取反回来,进行字符操作。
int x = dfs(t[u][0], (f ^ q[t[u][0]]));
int y = dfs(t[u][1], (f ^ q[t[u][1]]));
// 左右儿子遍历。
if(a[u] == -2) { // 如果是 &。
if(x == 0)
vis[t[u][1]] = 1;
if(y == 0)
vis[t[u][0]] = 1;
int res = (x & y);
return res;
}
else { // 如果是 |。
if(x == 1)
vis[t[u][1]] = 1;
if(y == 1)
vis[t[u][0]] = 1;
int res = (x | y);
return res;
}
} void update(int u) {
// 再扫一遍树。
// 我们之前只考虑了每个点的决定性情况。
// 但实际还应该考虑它的子树的决定性情况。
if (u <= n) return;
vis[t[u][0]] |= vis[u];
vis[t[u][1]] |= vis[u];
update(t[u][0]);
update(t[u][1]);
} int main() {
while(1) {
scanf ("%s", s);
if(s[0] >= '0' && s[0] <= '9') {
for(int i = 0; i < strlen(s); i++)
n = (n << 3) + (n << 1) + s[i] - '0';
break;
}
if(s[0] == 'x') {
int x = 0;
for(int i = 1; i < strlen(s); i++)
x = (x << 3) + (x << 1) + s[i] - '0';
cnt[++len] = x;
}
else if(s[0] == '|')
cnt[++len] = -1;
else if(s[0] == '&')
cnt[++len] = -2;
else if(s[0] == '!')
cnt[++len] = -3;
}
// 输入与一些保存方式。
Index = n;
for(int i = 1; i <= n; i++)
scanf ("%d", &a[i]);
stack<int> num;
// 后缀表达式-数字栈。
for(int i = 1; i <= len; i++) {
if(cnt[i] >= 0) { // 是数字。
num.push(cnt[i]);
continue;
}
switch(cnt[i]) {
case -1: { // 是 |。
int x = num.top();
num.pop();
int y = num.top();
num.pop();
Index++;
num.push(Index);
a[Index] = -1;
t[Index][0] = x;
t[Index][1] = y;
break;
}
case -2: { // 是 &。
int x = num.top();
num.pop();
int y = num.top();
num.pop();
Index++;
num.push(Index);
a[Index] = -2;
t[Index][0] = x;
t[Index][1] = y;
break;
}
case -3: { // 是 !。
q[num.top()] ^= 1;
break;
}
}
}
int Q, ans = dfs(Index, q[Index]);
update(Index);
scanf ("%d", &Q);
for(int i = 1; i <= Q; i++) {
int x;
scanf ("%d", &x);
printf("%d\n", vis[x] ? ans : (!ans));
}
return 0;
}

T4:(考场上降智了

一个数字三角形的变种。

其实就是需要多考虑一个从下往上走的情况,那就开两个dp更新嘛。

  • dp[i][j][1] 表示从下往上或从左往右走到 (i, j);
  • dp[i][j][0] 表示从上往下或从左往右走到 (i, j)。

这里指的是从上一步到这一步的状态。显然,答案就在 Max(dp[i][j][0], dp[i][j][1]) 里面。

然后就用类数字三角形的思路跑即可。

时间复杂度:\(O(nm)\)

#include <cstdio>
#include <cstring>
using namespace std; typedef long long LL;
inline LL Max(LL x, LL y) {return x > y ? x : y;}
const int MAXN = 1005;
const int INF = 0x3f3f3f3f;
LL dp[MAXN][MAXN][2];
int a[MAXN][MAXN]; int main() {
int n, m;
scanf ("%d %d", &n, &m);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
scanf ("%d", &a[i][j]);
memset(dp, -INF, sizeof dp);
dp[1][0][0] = 0;
for(int j = 1; j <= m; j++) {
for(int i = 1; i <= n; i++)
dp[i][j][0] = Max(dp[i - 1][j][0], Max(dp[i][j - 1][1], dp[i][j - 1][0])) + a[i][j];
for(int i = n; i >= 1; i--)
dp[i][j][1] = Max(dp[i + 1][j][1], Max(dp[i][j - 1][1], dp[i][j - 1][0])) + a[i][j];
// 因为不能重复走所以 dp[i][j][0] 不能被 dp[i - 1][j][1] 更新,同理 dp[i][j][1] 不能被 dp[i + 1][j][0]更新。
// 那么就只需要将走到左边点的最优解与上面或下面可以用于更新的最优解比最大即可。
}
printf("%lld\n", dp[n][m][0]);
return 0;
}

就当是重新回到起跑线上,凡是过去,皆为序章。

CSP.2020的更多相关文章

  1. 【初赛】CSP 2020 第一轮(初赛)模拟记录

    感觉初赛不过关,洛谷上找了一套没做过的来练习. 顺便写了详细的题解. 试题用时:1h 单项选择: 第 1 题 十进制数 114 的相反数的 8 位二进制补码是: A.10001110 B.100011 ...

  2. 日记 + sb错误

    置顶消息cpdd 1.29 完了,文化课没了 我是废物 1.28 更新了自己的副标题 前副标题:Future never has to do with past time,but present ti ...

  3. Solution Set - 神奇 NOIP 模拟赛

    \[\mathfrak{\text{Defining }\LaTeX\text{ macros...}}\newcommand{\vct}[1]{\boldsymbol{#1}}\newcommand ...

  4. [游记]2020/CSP - S总结

    2020 / C S P − S 总 结 2020/CSP - S总结 2020/CSP−S总结 这年的 C S P CSP CSP考的不是很理想,本来稳进的 C S P − J CSP-J CSP− ...

  5. 2020 CSP&NOIP 游记

    CSP初赛 CSP初赛 Day -1 早上打了模拟赛,T2寒假正好做过,然而还是还是被踩Orz,郑外NB!.中午出校吃了大盘鸡和拉面,还带回来了三瓶可乐. 初赛知识点看了两页不(看)想(不)看(懂)了 ...

  6. CSP/S 2020 退役记

    上一次的AFO记 上上次的AFO记 Day -INF 一条咸鱼的垂死挣扎. RP+=INF Day 0 出发辣. 早上来到机房,带上了准备的面包和泡面....然而后来嫌太占地方就没拿...草了. 而且 ...

  7. CSP初赛复习

    初赛复习 初赛一定要过啊,否则付出的那么多都白搭了! while(1) ++csp.rp,++csp.luck,++csp.scores; 历史 2020年开始,除NOIP以外的NOI系列其他赛事(包 ...

  8. Spring Cloud--尚硅谷2020最新版

    Spring Cloud 初识Spring Cloud与微服务 在传统的软件架构中,我们通常采用的是单体应用来构建一个系统,一个单体应用糅合了各种业务模块.起初在业务规模不是很大的情况下,对于单体应用 ...

  9. NOIP 2020 游记

    第一次写比赛游记,请多多指教! I. 考前 由于最近参加了太多太多比赛了,所以没有敲模板题: 考前一周:主要是在做 AtCoder 的题和 xjoi 的模拟赛,相当于恶补了一些套路吧! 考前一天:上午 ...

随机推荐

  1. 判断app访问还是web访问网站

    function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = ["Android", " ...

  2. Triple的使用

    public Triple<Long, Long, Double> getCarRunSummary(String did, Date startDate, Date endDate) { ...

  3. k8s部署之系统初始化(一)

    初始化 1.安装依赖包 yum -y install tree lrzsz nmap nc telnet vim wget lsof network-tools bash-completion bas ...

  4. 企业微信公众号告警Python脚本

    #!/usr/bin/env python # -*- coding: utf-8 -*- import time import requests import json import os impo ...

  5. LWJGL3的内存管理,第三篇,剩下的两种策略

    LWJGL3的内存管理,第三篇,剩下的两种策略 上一篇讨论的基于 MemoryStack 类的栈上分配方式,是效率最高的,但是有些情况下无法使用.比如需要分配的内存较大,又或许生命周期较长.这时候就可 ...

  6. python socket 二进制

    问题 在工作中经常会用到socket传输数据,例如客户端给服务器发送数据(双方约定了数据格式),在交测之前,自己用python写个接受数据的server,解析下拼成的数据格式是否正确.用python写 ...

  7. vue实现带logo的二维码/商品条形码/打印商品吊牌

    一.带logo的二维码 1.安装 npm install vue-qr --save 2.在页面或组件中使用 <template> <div id="qrcode" ...

  8. .Net 5 正式版RTM 发布

    下载连接 https://dotnetcli.azureedge.net/dotnet/Sdk/5.0.100-rtm.20515.8/dotnet-sdk-5.0.100-rtm.20515.8-w ...

  9. python_登陆验证文件上传下载_socket

    client.py import os import sys import json import struct import socket # 下载--接收文件 def download(sk): ...

  10. Docker - 解决 Error response from daemon: driver failed programming external connectivity on endpoint tomcat9999

    问题背景 执行 docker start tomcat 报以下的错误 Error response from daemon: driver failed programming external co ...