注: 本文写于11月17日傍晚。
赛前
疯狂颓废。
前一天上午打了一下excrt的板子,看了一下(O(1))快速乘等一些小技巧。
感觉自己一年比一年颓废……吃枣药丸
今年高一,不管怎样心态都和初中时不一样了吧。初中时打挂了还能庆幸自己年轻,现在打挂可真的就不是闹着玩了……
看考场,发现和lrh&ll一个考场。我怎么觉得17年的时候我们就一个考场呢(虽然好像不在一个组)
考前继续立flag,希望不要哭着出考场吧(noip2018&pkuwc2019两次尝试失败)
11.16 (Day 1)
我的Day1体验和大多数低水平选手基本一致。
顺序看题。
8:45左右写完T1. 一遍过了样例,但是(n=64)莫名会挂。最后把(1llu<<n)-1
强行改成llong qwq[N+3]; qwq[1] = 1llu; for(int i=1; i<=N; i++) qwq[i] = (qwq[i-1]<<1)|1;
才过。
9:10左右写完T2. 本来觉得做法很虚容易写挂,反复检查了一下,结果一遍过样例了。又去写暴力,9:25左右拍上了。
1h切了前两题,这势头不对,难道又是全场ak的day1……我打开了T3
这什么玩意??他说的交换数字结果下面配图很明显是在交换编号啊???顿时蒙蔽,举手提问题目是否有问题,得到了No response的热情答复。
看了半小时,发现那个图居然和我的习惯不一样……那个圈里的数是数字圈外的数是编号……
这时候还有2h, 可是仔细看看这题我怎么一点思路都没有啊……感觉情况非常的复杂,不是很好处理……
打了个10分暴力,又各花了0.5h想两种特殊形态的部分分,依然毫无头绪
什么……别告诉我我2.5h刚一道联赛题只拿10分……我不接受……我不同意……
时间继续流逝,我又先后尝试思考正解、链、菊花结果屡屡失败。
我感觉想吐……
然而灵光并没有闪现。
day1结束,期望得分(100+100+10=210)
出考场之后强忍住没有掉泪,不过心态也基本崩了……17年和18年我的day1分别是(230)和(270), 今年最多(210)了……真的有一种支撑不住的感觉
过了一小时和别人交流了一下,发现qdez基本都(210)……只有lky似乎想出了T3的(O(n^3)), 结果他写炸了似乎要爆零,惨惨。
又去群里看了下发现大家都在抱怨T1T2sbT3难……突然感觉心态好了一些呢。
看到知乎上题解发出来了,T3的50其实挺套路的啊……为什么我就没想到呢
傍晚gd初三巨佬zjr来问我估分,他(235), 还说GD全场都超过(210)了……我又开始崩了
最后听说yamf T3都没得超过10分,rqy&myh AK了,wqy T3没做出,听myh说集训队有一半人不会T3……那这么说的话这场就没有什么区分度了,我就当今天什么都没发生,day2加油。
11.17 (Day 2)
传说中的有区分度的day2终于来了。
逆序看题。
T3, 怎么又是数据结构,弃弃弃
T2, 看上去像斜率优化?毒瘤,弃弃弃
T1, 计数??怎么现在计数都被放到T1了?没办法,刚刚刚
8:40 我终于看懂题了嘤嘤嘤
8:42 第一思路是枚举做了多少菜,发现不可做
8:46 转换一下思路发现最多一道菜会违反一半的限制,可以枚举,然后就相当于这一个比别的都多,dp一下,(O(mn^3)),一脸懵逼
8:48 发现我的转移枚举选哪个是废的,(O(mn^2)), 应该没假吧
写了滚动数组dp, 因为清空问题挂了15min,调过大样例的时候大概是9:10
计数题……不拍了不拍了不虚,看T2
看到样例3, 一个(28)位数赫然地摆在题面里,出题人你真的不嫌自己毒瘤吗
冷静了一下,似乎和斜率优化没什么关系?有一个显然的(O(n^3)) DP是设(f[i][j])表示当前划的最后一段末尾是(i), 前一段末尾是(j), 发现转移可以优化,(O(n^2)).
写完了,我怎么又一遍过样例了??感觉这次画风好奇怪啊,代码难度大幅降低?还是我太菜了想不出代码难度高的正解?
又想了一会没想到什么比较好的优化,感觉是个贪心又没有贪心策略,于是开了T3.
(40)分显然白送,链显然白送,然后呢……完全二叉显然白送……吗??我感觉我好像不太会写啊.jpg
于是先去写了一个(O(n^2)), 又一遍过样例了,今天这是怎么了……链的(15)分过会再写吧
想了一会正解,感觉没什么思路,只想到了一个求子树内重心的做法: 重心显然满足到所有节点距离和最小。那求距离和是一个dp, 我把dp数组表示成(at+b)的形式, (t)是树总大小,然后线段树维护凸包,就可以轻松应对子树内了……子树外……没啥想法啊……
又看看数据范围,(nle 3 imes 10^5,Tle 5), (O(nlog n))都很难通过,线段树维护凸包可以去死了……
我是不是要止步(100+64+55=219)了?这样的话我离考过去年还差(3)分,不甘心……还有1h40min, 我能怎么办……
现在我还有两个选择,一是想T2正解,二是莽T3的完全二叉树(因为我自知数据结构水平太低想不到正解)。我决定先想一会T2,然后再去想T3.
打出DP表,发现固定(i)在合法的前提下(f[i][j])随(j)的增加而不升,然后又证了一下感觉挺显然的,那么其实就是要让每次划分最短。哦这么显然的结论我都要打表观察……我是个弱智么?!
此时我过于激动,想都没想写了个(O(n))双指针找决策点,一发过了前两个样例,好,我稳了!测第四个样例(第三个是高精测不了),比答案大了好多……
难道结论错了?拿暴力程序跑了下,(dp)数组是单调的啊??那是怎么了??哦,决策点显然不能直接双指针求……我果然是个弱智
那怎么求啊?似乎只能二分+线段树(O(nlog n))? 线段树……我真的能写出来吗……
T3还有(15)分暴力没打,T2还生死未卜,看着右下角的时间11:01, 浑身无法阻止地冒着冷汗……
冷静一下,每次覆盖,单调栈就行了!可是还有两个该死的二分去不掉,(O(nlog n)), 整理一下思路,开始写吧……
比我想象中的好写一些,十几分钟写完了,调了一会发现二分的方向反了,改过来过了所有样例!
还有30min, T2来不及对拍,快马加鞭写了个T3的(15)分暴力, 这恐怕是我两天写得最不顺的一个代码,挂了好多次……
11:47, 我终于调过了样例,期望得分(100+88+55=243).
最后十几分钟觉得对拍意义不如肉眼检查,于是检查了十几分钟文件名、输入输出、数组和空间,T2精打细算开了(1000 ext{MB}).
结束的那一刻,我把T2的数组从(4 imes 10^7)改成了(10^6). 我不配写正解,我不配开大数组……
总期望得分(100+100+10+100+88+55=453), 感觉垫底水平……但愿别挂……
不过似乎刚好能考过去年……?
考完后直接返回(没有掉泪,flag成功达成)。途中交流了一下,hyw和nyd怎么都说自己T1不会写了(84)喵喵喵?
hyw貌似考得不是很好,估分(84+64+55=203)左右,lky好像也不太好,jxp和zkt估分(100+64+75=239), 不知道gmt和yzx怎么样。(这也许是qdez今年最有竞争力的6个人?)
比我低两级的巨佬sqy估分(245), Orzzzzzz... 我被本省初中生吊打,没救了……
在gzez一起训练的scx,lh貌似直接心态崩溃……scx昨天(210)大众分,今天自称t1没调出来,写了个指数级暴力;lh自称d1t2写挂……默哀
zjr自称估分(219), 但是我不会忘记他外号“张假瑞”的由来(大雾)
看上去大家得分都不是很高,如果我不挂的话还是有希望的……但愿别挂分……
总结与反思
这次也许我最想质问自己的一个问题是,为什么我经过这么长时间的训练,还想不出Day1T3的50分那种比较套路的东西?
也许我会找出借口: 全SD也没几个人想出T3的50分啊。可是,所谓竞赛就是要选拔出最尖端的那一撮人对吧。现在搞OI的人越来越多,如同千军万马过独木桥,如果我永远抱着别人都不会我也不会的心态,每次都拿大众分,还有什么胜出的可能?
现在的OI大概已经告别了那个比拼熟练度和稳定度的时代,因为熟练和稳定已经是对一个OIer的基本要求,而非用来区分选手的标准。在这种情况下,假设我连基本的套路都掌握不明白,又没有过人的天赋来做出神仙题,大概只能成为大佬的炮灰吧。
初二,初三,高一,尽管我自己在不断进步,却赶不上时代进步的速度。去年ZR十连测,我的成绩最后基本稳定在20名左右。今年ZR十连测,我的成绩依然在20名左右(而且失误掉下去的次数还在增加),永远成不了最尖端的那一部分,省队将与我有何缘?
因此希望自己以后做题的过程中一定要多积累一下值得借鉴的思路,并对这些套路有足够的敏感度。(当然也不能过敏,忽视了反套路思维的训练)
除此之外,自己的努力程度也明显不够。高一的四分之一已经过去,如果再不拼尽全力,明年成了一条命选手,蓦然回首发现自己枉度五年光阴,将是何种情境,自己心里清楚就好。
赛后
upd 11.18: 发现day2t2我居然把一个单调的东西放在单调队列里二分……我是智障
upd 11.18: 在学校上着课,突然脑中如雷击般闪过一个问题。
我的day1t2。
嗯,我代码原来是这样的
const int N = 5e5;
int cnt[N+3];
本机对拍(10^5)组(n=500)的数据没出现问题,但考试结束前发现cnt
数组需要用到负下标,于是改成了:
const int N = 1e6;
int cnt0[N+3]; int *cnt = cnt0+N;
更致命的是,我改完之后连测都没有测直接交了上去。
附正确写法:
(1)
const int N = 5e5;
int cnt0[(N<<1)+3]; int *cnt = cnt0+N;
(2)
const int N = 1e6;
int cnt[N+3]; //因为n<=5e5, 因此负下标会爆到前一个数组的后半部分,不产生任何影响
多少条正确的道路,我却偏偏走上了错误的一条。
吊 死 于 括 号 树 上
预估分(100+0+10+100+88+55=353)。
高一容不下失误,一招不慎满盘皆输……
upd 11.20:
经过数个昼不醒夜不寐的日夜,代码终于发了。
lky和hyw坚持认为我不可能开错day1t2的数组,要先测我的day1t2。我拒绝了。
也许这种考验人心脏的事情,还是独自进行比较合适。
先测了一发day1t1,(100)分过了。
手开始哆嗦。
我的记忆有99%的概率是准的。那1%的“偏差”,若有若无,却是唯一的希望。
我想象着看到某个场景时的如释重负,然而脑海里却充斥着看到另一个场景时的绝望与无助。
也许我可以先测完别的题再来测这题?
算了算了,别的题再有挂的更难受。
鼠标移向那个文件
……
突然传来hyw的声音:“你没写错,你写的是N<<1
”
我想起前一天lky戏弄我,一本正经地说代码已经发了,我写的是N=1e6,cnt[N>>1]
,害得我半信半疑地问了半天才确定他在骗我。然而这在我看来只是不屑的嘲笑。
“草,你怎么也像lky一样假我啊”
“不,真的……” 然后我跑到她电脑前,看到了那段昼思夜想的代码:
const int N = 5e5;
int cnt0[(N<<1)+3]; int *cnt = cnt0+N;
那一刻的感觉无法描述。
松了一大口气之后,我把剩下四道题一起交了上去。
(10)。
(100)。
(64)?!
(55)。
看到(64)的时候,我还有些许不相信,后面的点答案都是(0)使我更加疑惑。也许是我交的时候搞错了什么?
重交一发。依然是(64)。
什么?如果单纯是WA了我还可以接受,但是我输出的都是(0),这怎么可能?我在考场上用(88)分的代码过了大样例的!
INF
设小了?不对,答案还不到(10^{18})啊
代码:
int n,typ;
llong a[N+3];
namespace BruteForce //64分代码
{
void solve()
{
for(int i=1; i<=n; i++) scanf("%lld",&a[i]),s[i] = s[i-1]+a[i];
......
}
}
namespace GG //88分代码
{
void gen()
{
//读入typ=1的数据
}
void solve()
{
if(typ==1) {gen();}
......
}
}
int main()
{
//freopen
if(typ==0) {for(int i=1; i<=n; i++) scanf("%lld",&a[i]);}
scanf("%d%d",&n,&typ);
if(n<=5000) {BruteForce::solve();}
else {GG::solve();}
return 0;
}
初始(typ=0,n=0), 所以并没有读入a
数组,但BruteForce
中有读入a[i]
,GG
中没有!
真相大白:在用(88)分代码过了大样例后,我决定把a
数组的读入放到main
函数中。但是脑子突然短路,我把读入a
数组放到了读入n
的前面,并且忘记从暴力中删掉这一行,于是我的代码长成了这样。
然后,重新测大样例,顺利通过,比赛结束,匆匆离场。
我本来只能通过这题(88)证明自己不是个什么都不会的暴力选手,结果它挂成了标准的暴力分。
最悲哀的是,我没有写挂代码,而是在数据分治这种地方阴沟翻船。
改了一发读入,(88)。
可喜可贺可喜可贺……
(100+100+10+100+64+55=429),这个结果基本是板上钉钉的事了。
得到这个结果,不知道该说什么,是幸运?还是不幸?……
终究难逃考不过去年的命运,尽管由于题目难度天差地别,我的排名还不到去年的三分之一。
如果我day1t2真的开错了数组……会怎样呢?
更有甚者,如果我day1考完后意识到这点,day2会考出怎样的成绩呢?是否会在考场外大哭一场,重演NOIP2018的悲剧?
另一方面,如果我day2t2没写挂数据分治,稳稳拿到了(453)分,又会是怎样的一种爽快呢?
虚无。现实或好或坏,毕竟是现实。思考那些并没有什么意义。
灵光闪现的一刻,11:01的电脑时钟,浑身不停地往外冒的冷汗,写代码时的紧张与焦急,过掉大样例时的如释重负……
等于什么?等于如释重负后的脑袋一热,两行错了位置的代码,和一行忘记删除的代码。
听起来有些搞笑……
总结中多出轻描淡写的一句话:离场前一定好好检查数据分治和读入输出,最好用每档部分分把大样例过一遍。
仅此而已。CSP2019完结。