• CSP-S2019游记


    注: 本文写于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完结。

  • 相关阅读:
    [Noip2017]逛公园
    [NOI2005]瑰丽华尔兹
    codeforces 558E A Simple Task
    bzoj1812 riv(树形背包)
    bzoj 1009 GT考试
    bzoj1030 文本生成器 Trie图+dp
    bzoj1500 维修数列(splay)
    [NOI2008]假面舞会
    测试用例的基本知识
    使用Xmind编写测试用例
  • 原文地址:https://www.cnblogs.com/suncongbo/p/11877780.html
Copyright © 2020-2023  润新知