Skip to content

Tag Archives: NOI

ACM新手上路总结及感言

(6月5日小更新,增添一些细节。) 儿童节那天,七场新手赛全部结束。当天睡得很早的我,第二天早上才看到总积分的榜单,对着那些空洞的数字,对着那些浸透多少人奋斗与梦想的数字,我看了很久。 本篇的标题早就定好了,就不改了。不过,我想这篇文字不会单单总结这半年来参加的ACM/ICPC活动,我希望它是我加起来不到两年的OI+ACM征程的回顾,和对将来不知会延续多少年的竞赛之路的展望。 ~~~~~~~~回首往事的分割线~~~~~~~~ 两年前的此刻,我还不知算法为何物。(现在的你,真正理解什么是算法吗?) 两年前的六月底七月初的某个不确定的日子,除了C语言的语法什么都不会的我,第一次以竞赛的目的走进高中的机房。开始了,我的OI征程。那天上午,做了一套NOIP模拟题,得分130。记得那四道题中竟然有一道平衡树题。所以说……我做的第一套NOIP模拟题真是太不厚道了!(现在的你,已经参与过不知多少次这样那样的模拟赛的命题了吧,有几道是自己满意的好题目呢?你发现问题的能力比那时有多少增强呢?) 两年前的七月与八月,正是最热的时期,也是我如饥似渴获取知识的时候呢。在那个暑期集训结束的时候,我再一次对照了NOIP大纲,确定其中知识的盲点已经不存在了。大概也就是在这个时期吧,第一次拿了学校OI小组内部比赛的rank1。呵呵,那些个阳光灿烂的日子,我心里想的一定是随随便便拿个NOIP一等奖然后回去专心钻研我的数学竞赛。就是从那时开始狂妄与轻浮的吧?(现在的你,把这些坏毛病改掉了多少呢?) 两年前的九月十月十一月,一起学OI的同学,都在进行最后的冲刺吧。而我呢?显然没有尽全力。在论坛上灌水,跟MM聊天,在网上闲逛……我想这些活动的时间,加起来会超过这一段我做题学习的时间吧。觉得自己什么都会了,NOIP一等奖如探囊取物。(现在的你,每天几个小时坐在电脑前面时,哪些活动占的的时间最多呢?) 两年前的十一月十七日,NOIP2006复赛的前一天,在郑州。关于那天的记忆,大部分都已变得模糊。记得有跟某MM一起逛街,却把她的名字忘了。记得买了个钱包,却忘了是买给谁的。可以确定的是,当天晚上的九点到十一点,哦,也许是到第二天凌晨,我都待在旅馆里一起来的女生的房间里,跟她们很愉快地说笑,其间教她们唱了《隐形的翅膀》这首歌。(现在的你,对音乐的欣赏风格发生了一次又一次的转变,很久不听张韶涵的歌了,把《隐形的翅膀》的歌词也忘得差不多了吧,也听了许许多多不同风格的歌,可是,像当初一样打动自己的歌还有吗?) 两年前的十一月十七日上午,NOIP2006复赛,郑州轻工业学院,机房C。对着完全写错的DP,没有检查和测试,心里想的却是要不要用四边形不等式优化。面对稍微有点变化的背包问题,狼狈地发现连01背包都写不出来。在最后半小时匆忙地写了个蘑菇题。出来以后对老师信心满满的说两百分没问题。(现在的你,代码的速度和准确度自然有了很大提高,可是,为何像那时一样的低级致命错误仍然在重复呢?) 两年前的十一月十七日下午,坐车回家。在现场等到了评测结果的老师打来电话,告知我100分的可怜成绩,并一遍遍问我是否申诉、复评。我瞬间回忆起了那道寄托希望的DP的低级错误,明白这个成绩是绝对准确的,变得颓唐。跟家里人打电话,几乎哭泣。(现在的你,又经历了许多次失败,可是,面对失败的态度有改进吗?) 两年前的十二月开始,我被迫承认不得不在OI的路上走下去,设想中的一次小插曲式的短途旅行,变成了贯穿整个高中阶段的OI征程。每天中午到机房做USACO Training,瞒着家人,瞒着班主任,他们都以为我会在宿舍午休。教室里,趁老师不在的时候,读Weiss的《数据结构与算法分析》,读《算法导论》。疲惫,也一点一点的脱胎换骨。(现在的你,明白了当时无法接受的失败完全是因基础不扎实所致,那么,在你现在学习中的各个方面,基础扎实吗?) 一年前的三月三十一日晚,一次成绩还算满意的高考模拟以后,没上晚自习,而是到了机房,正式停课准备省选。记得非常清楚,当晚AC了卡了我很久的 Cryptcowgraphy 一题。第二天开始学习网络流,继续做USACO Training。(现在的你,面对那种程度的题目自然会觉得小菜一碟,做题做得越来越快,可是,有多久,你忘记了那种AC了困扰自己几个月的题目的欣喜?) 一年前的四月的前二十天,在为21日的省选而奋斗。4月1日到4月5日,用了五天时间,把USACO Training从4.2做到了6.1,通关了,后来写了篇《USACO心得》。Bellman-Ford、最小后缀、虚二叉树、匈牙利算法、RMQ、KMP、LCA、图的割顶与桥、并查集、凸包、高斯消元法、收缩强联通分量、树状数组、Splay、Treap……这些算法和数据结构,都是在2007年的这20天里学的。(现在的你,还会有像这20天一样充实的学习过程吗?) 一年前的四月二十一日,省选,HAOI2007,又是郑州轻工业学院。提包里装着打印出来的几十页的算法,只是为了比赛前的前一天晚上看上两遍。结束以后,对老师说,展现出了自己的全部真实实力,但也没有超常发挥。第二天的学校门口,已出现“荣获河南省第一名”云云的大字。(现在的你,能做到在每次比赛中都“展现出了自己的全部真实实力”吗?) 一年前的四月最后几天,以及五月六月七月,怀揣着NOI金牌的梦想奋斗。大多时间,坐在属于我一个人的空荡荡的的机房里,看书做题。期间去郑州101中学,省队集训,非常好的朋友、兄弟。Suffix Array的O(NlogN)和O(N)算法,Network Flow的SAP、Dinic、HLPP等算法,字符串匹配自动机,最小树形图,博弈论的SG函数理论,线段树,大概是在这段时间学习的。《组合数学》、《Code Complete》是在这段时间读的。还学用了Emacs、GDB、gprof等工具。用梦想取暖的简单生活。(现在的你,还能找到一个单纯明确的梦想为之奋斗吗?) 一年前的七月倒数第二天和八月第一天,遥远的福州,NOI2008的两试。铜牌,我的OI生涯的句号。我软弱到不愿提起那次经历。(现在的你,比那时变坚强了吗?) 一年前的十一月十六日,在郑州的河南省实验中学逸夫楼三层的机房里,写下了充满梦想的文字,后试图约xtt出去未果。次日,NOIP2007,满分。(现在的你,还记得写下那些文字时的心情吗?) 从那以后,我的生活真的与OI两个字没什么关系了。 好了,以上跑题完毕,下面开始说本次ACM新手上路。。。- – ~~~~~~~~跑题完毕的分割线~~~~~~~~ 总结一下已知的缺点和解决方案: 思维广度不够。一些完全在能力范围内的题目,不知为何当时就是想不到。解决方案:似乎只能多做题多思考吧,切ZOJ2.0上的题目。 对STL不熟悉,导致每次用到几乎都要查文档。解决方案:抽空把文档看一遍,多用。 数学功底不够,尤其是组合数学很需要加强。解决方案:再细读一遍《组合数学》。 计算几何和数论根本不会。解决方案:不会就学呗。计算几何看lrj的书好了,手头还有一本清华社的《计算几何——算法与应用》;数论还不知道该看啥。 某些算法(比如说网络流)的实现,特别是应用,遗忘得太多了,要重新拾起来。解决方案:仔细重读一遍Weiss的书以及CLRS好了,这次读英文版的,注意习题。(或者读别的算法书?) 看题不仔细。解决方案:比赛时别太匆忙,多花点时间仔细看题利大于弊的。 体力和意志力不行,每次比赛都坚持不到最后就不写了。解决方案:还不知道。找人组队可以很大程度上弥补体力的不足。但如何培养“不到最后一刻决不放弃”的意志力呢? 当然啦,上面光说缺点了,其实我的优点更多,比如说代码写得快、算法会得多……还有其他好多好多啦都说不完的。但是我这个人这么谦虚,是绝对不会对别人炫耀甚至提起自己的优点的。我一直都是那样的自省、内敛与深沉……(以下省略二千字- -) 感言: 感谢 Channel [V]、MTV……哦,不好意思拿错稿了掐了别播啊。 不到半年的ACM/ICPC经历,让我懂得的最重要的事情,是团队合作。我知道了,ACM不是单打独斗,个人能力很重要,但良好的团队合作更重要!(本段做字正腔圆感情充沛状,末尾语调上扬,眼神坚定。) 需要做的事情还有很多,很多东西还要学习,不仅是知识方面,也包括“如何平衡ACM与其它各种事情的关系”之类命题。但是快期末考试啦,除了考虑出题以外,考完之前就不安排ACM方面的计划啦,考试完了就该暑期集训啦。 所以,千言万语,赶紧汇成一句话:期待暑期集训的精彩吧! 梦想: 我要登上 ACM/ICPC World Final 的领奖台。 附:[转载] For […]

给正为4月26日奋斗的学弟学妹们

大约是去年侥幸得了河南省选第一的缘故,好几个下一届的学弟学妹找我问怎样准备省选,在这边统一回答一下。 第一,把USACO Training做完。我曾经不无天真地认为,只要做完了USACO,进河南省队就没有任何问题。然而事实上,按照07年的情况来看,这个判断好像真的没有例外。在现在时间比较紧的情况下,写不出来就看题解没问题,但要保证看完题解以后代码是自己独立完成的,且你真的理解了这题目的算法。 第二,学一些最常用的高级数据结构与算法,但不必全学,按照自己的时间安排和兴趣选学好了,因为谁也不知道会考什么。参考清单:网络流(最好学Dinic算法,要知道最大流最小割定理的内容)、Treap或者Splay、KMP算法、Trie树、线段树、求割点和桥、收缩强联通分量。 第三,找一些高质量的套题限时做。这样的目的一方面是查漏补缺,另外是培养比赛的感觉。推荐山东、浙江、天津、重庆、河南的一些省选题,难度适中且比较贴近国情。也推荐USACO历次月赛的Gold和部分Silver题,这些题的好处是有完整的题解,当然阅读英文有障碍的就很遗憾了。 第四,把心态放低,告诉自己省选没有那么重要,进NOI并不是值得赌上全部去追求的东西,若选不上不一定是坏事,在河南这种太受歧视的地域,也许有保送资格以后把文化课搞好才是更合适的道路。把心态放稳,告诉自己河南是弱省,根本没什么强人,只要发挥正常就能进。心理调节很重要,我的经验是,当你心中不会经常出现“省选”或者“省队”这些字眼,而只会专注于一个一个的算法、一道一道的题目时,状态是最好的。 第五,需要更多心理调节以及任何合理的帮助可以直接打我手机,号码给我留个言就会告诉你,MM特别欢迎。

NOI训练近期计划

近期必须要提高效率。用二至三天的时间详细记录时间表,以提高效率。每天早计划晚总结。 必须要做的是把Linux装好,Emacs和Vim都试试。总结一下自己用Dev-C++时需要的全部功能,然后用某种编辑器全部替代了。GDB也可以试试,如果真的很爽的话就用Emacs了。Vim最无奈的就是编译了,感觉上比较好的解决方案还是写makefile,这样的话多Tab要搞清楚。 算法方面,一个必须要掌握的就是块状链表,考的可能性很大,所以说完全可以花一两天甚至更多时间仔细研究仔细实现,除了NOI2005那个题以外还得找别的练习一下。网络流再写一两遍relabel-to-front,感觉一下,有空的话写个HLPP也行,Dinic写不写似乎都没关系,毕竟距离标号已经写得很熟了。 平衡树是另外一个大重点,一定要多练些麻烦的题练熟了。把递归Treap和Buttom-Up Splay要练到十分钟/十五分钟能默写的程度。 字符串处理方面。Trie图的相应的那几道题目做了也就没什么需要多说的了。最好搞懂“扩展KMP”是什么东西。后缀数组,如果遇到了非得O(N)的题再考虑学Skew Algorithm,否则就把nlogn的好好掌握就行了。 做题的话,SGU应该在一周内告一段落。下一步就去SPOJ攻难题吧,也可以照着网上的题目推荐内容做些POJ/Ural之类的补充。另外发现TopCoder的题目很不错,对照着题目/题解欣赏下似乎很好。 效率,一定要注意效率。珍惜时间,绝对不启动浪费大块时间的娱乐计划。

实时离散化:NOI2003 editor另解

NOI2003的editor(文本编辑器)一题的标准解法是“块状链表”。这个东西我以前没有写过,怎么想都觉得无法将这个东西妥帖地实现。找到的一个这道题的C++程序竟然有三百多行,让我看得着实很恶心。这道题能不能不用这种很不优美的数据结构来解决呢?答案是肯定的! 我把我解决这个问题时使用的技术称为“实时离散化”。首先解释离散化,一种合适的理解就是将需要处理的序列中的某些连续的区间当作一个元素来操作,以减少总的元素数量。对于这道题而言,如果我们事先能够知道“在哪些字母的前后会插入一个区间”“在哪些字母的前后会有区间被删除”,把这些字母称为“关键字母”,用一个关键字母来代表它与它后面的所有非关键字母,就可以大大的降低时间复杂度了。因为INSERT和DELETE的操作总数不超过4000次,“关键字母”的总数也不会超过4000*2个,这样就相当于所有的插入删除操作都在最多8000个(而非2000000个)元素组成的串上进行,当然就会很快了。问题是,我们无法在一个字母被插入时判断出它是否会在将来成为“关键字母”,也就是说,无法像某些题目一样只做一次初始的离散化,我们的“离散化”必须是“实时”的,也就是,必须实时的维护可以被一同处理的区间。 听上去有点玄妙,其实很简单。用一个很长的字符数组保存曾经被插入的所有字符串,当前正在编辑的文本用一个区间的数组来表示,每个区间代表它在前述字符数组中的位置。当需要在某个区间的中间插入时,只需按照这个被插入的位置将这个区间分裂成两个,再在两个新形成的区间的中间插入就可以了。同样,删除时也只需要按照需要被删除的文本两端将它们所在的区间分裂成两个,然后删除连续的若干个区间就可以了。设修改操作一共做了M次,则任何时候的区间总数不会超过2M个,所以每次操作的时间复杂度都是O(M),所有修改操作的总时间复杂度是O(M^2),而且常数很小,由于M<=4000,是完全可以承受的。INSERT和DELETE都实现了,GET也很好实现,挨个输出就行了,PREV和NEXT更是常数时间而已,最多可达到50000次的MOVE呢?如果每个MOVE的复杂度也都是O(M)似乎会有超时的危险。注意到这样一个明显的事实:若有连续的MOVE操作,只需要做最后一次的操作即可。经过这样的处理,需要实际做的MOVE操作大约也只是O(M)的级别。 对于这类在序列上进行添加、删除、反序等修改的题目来说,设修改操作有M次,序列的最大长度为N,块状链表的复杂度是O(M*N^0.5),“实时离散化”的复杂度是O(M^2)或者O(M^2+N),可见它在很多情况下是很有代替块状链表的可能的。对于某些题目而言,我认为它是相对于块状链表的一个更高层的抽象,所以编程要简单优雅很多(我的堆砌着大堆短函数的拖沓程序用了156行,其中核心的部分仅有不到100行),也不失效率。对于本题来说,我的程序可以P4 2.oG的电脑上最大数据1.6s左右,是可以AC的。但是,“实时离散化”还是不能完全代替块状链表,比如说当M与N同阶的时候就会退化成O(N^2)(因为已经失去了离散化的意义了),而块状链表仍然保持着O(N^1.5)。 示例程序: editor.cpp

NOI计划,五月下

1,《组合数学》《Code Complete》两书看完并写完全部的缩写/笔记,这个尽量快些,每天都要有进度。 2,后缀数组要会O(n)算法,height相关的东西要写熟;后缀树的话,至少会个O(nlogn)吧,要多做几道相关的题。串处理方面一定要加强,看论文,看CLRS。 3,做SGU,所有1000+的题目要都做掉,然后写一个阶段的总结。然后开始做600+的,尽量也都做掉。看看有没有相关的好玩儿的数据结构/算法(估计不太有)。 4,本月暂时不学Vim和Linux。 5,不能荒废时间,放松一下可以,你知道怎么样算荒废时间。