﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Mato is No.1-随笔分类-AHOI</title><link>http://www.cppblog.com/MatoNo1/category/16328.html</link><description>Mato是一只超级大沙茶……但他一直以来都想成为各项比赛都No.1的神犇……</description><language>zh-cn</language><lastBuildDate>Tue, 18 Jun 2013 02:12:26 GMT</lastBuildDate><pubDate>Tue, 18 Jun 2013 02:12:26 GMT</pubDate><ttl>60</ttl><item><title>【复仇之战】AHOI2013 Round2 总结</title><link>http://www.cppblog.com/MatoNo1/archive/2013/06/17/200747.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Mon, 17 Jun 2013 14:37:00 GMT</pubDate><guid>http://www.cppblog.com/MatoNo1/archive/2013/06/17/200747.html</guid><wfw:comment>http://www.cppblog.com/MatoNo1/comments/200747.html</wfw:comment><comments>http://www.cppblog.com/MatoNo1/archive/2013/06/17/200747.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/MatoNo1/comments/commentRss/200747.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/MatoNo1/services/trackbacks/200747.html</trackback:ping><description><![CDATA[<div>前言：<br />从2006年的全国第一，到2012年的全国第二十；<br />从国家队每年必有，到正式选手NOI Ag都拿不到；<br />时间可以改变一切，仅仅几年，我们共同见证了一个省从强省变成弱省；<br />而无比奇(keng)特(die)的省选题，又使得许多难以想象的事情发生了；<br />不知现在，还有谁记得一年前的那场风波，两年前的那场风波，三年前的那场风波；<br />不知现在，还有谁记得那些被奇(keng)特(die)的省选题和谐掉的众神；<br /><a title="相关链接0" href="http://tieba.baidu.com/p/757980215">相关链接0</a><br /><a title="相关链接1" href="http://tieba.baidu.com/f?kz=1614015738">相关链接1</a><br /><a title="相关链接2" href="http://tieba.baidu.com/p/1614320034">相关链接2</a><br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />今年，安徽省选终于不再是一场闹剧。<br />希望这能成为一个转折点。下面进入正题。<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br /><br />本沙茶还是考废了&#8230;&#8230;6题有3题被卡常数，而且卡到和暴力差不多的得分&#8230;&#8230;<br />不过毕竟复仇成功了&#8230;&#8230;好像还进了A队&#8230;&#8230;<br />不过像我这么弱到NOI也是被虐的份&#8230;&#8230;<br /><br />下面上题解：<br />【Day1】<br />coin：<br />首先那个贪心性质是比较好看出来的囧&#8230;&#8230;就是如果每个面值都是上一个面值的正整数倍，则要得到一个价格的最小张数，总是先用最大的，不够了再用第二大的&#8230;&#8230;以此类推。<br />（证明：假设价格为s，某个方案(a1, a2...am)(ai为第i大的面值使用张数)对于最大的面值不是按照这样的，则有s-a1*v1&gt;=v1；若a2*v2&gt;=v1，则将(v1/v2)张第二大的换成一张第一大的显然更优，若a2*v2&lt;v1，则可得s-a1*v1-a2*v2&gt;=v1-a2*v2&gt;=v2，可以对第三大的继续分类讨论，这样一直到第m大的，必然会有一个出现可换成更大面值的情况，也就是该方案必然不是最优方案；如果最大的面值按照这样，后面的面值不按照这样，仍然如此）<br />这样只要所有面值确定，配成任何一种价格的最优方案也就确定了，且可以随着面值从大到小的一一确定，不断更新最优方案；<br />由于本题价格&lt;=100000，所以考虑搜索。一开始搜最大的面值，然后在搜后面的面值的时候，只能枚举其因数。优化：<br />（1）初始定界：根据样例2+简单分析可以得出，使用2的幂的面值是一种比较优的方案，因此用它进行初始定界，可以大大方便后面的卡界；<br />（2）容易证明，如果所有价格中最大的为maxw，则最大的面值必然在[maxw/2, maxw]之间；<br />（3）很重要的剪枝：容易证明在最优方案中，相邻两个面值的比值必然是质数（否则设vi/v(i+1)不是质数，存在&gt;1的因数d，则加入vi/d这个面值以后&#8230;&#8230;）。因此，只需要预处理出2~100000间所有数的质因数即可；<br />（4）一些启发式优化（卡界）；<br />（5）卡时；<br />综合使用以上方法可以得到85~100分；注意搜索中的数组分层问题；<br /><br />cube:<br />被卡常数了，真悲剧&#8230;&#8230;<br />本题的猥琐之处在于它的时空限制，时限1s，空限64M&#8230;&#8230;给跪了！！！<br />只要求出(0, 0, 0)-(200, 200, 200)间的每个格子是否被覆盖，然后再做一次floodfill就行了囧&#8230;&#8230;<br />实现方法有很多，最好的是三维树状数组（改段求点，一个数组即可，且可以用short）。<br />问题是，本题的floodfill如何实现？递归DFS，爆栈；人工栈DFS，MLE；BFS，在压位的情况下可以勉强卡过空间，但常数被卡了&#8230;&#8230;<br />（求神犇好的解决办法囧&#8230;&#8230;）<br /><br />square：<br />首先两个不相交子矩形要么在X方向上不相交，要么在Y方向上不相交，要么在X、Y方向上都不相交&#8230;&#8230;（废话）<br />因此结果等于(X方向上不相交的全黑子矩形个数)+(Y方向上不相交的全黑子矩形个数)-(X、Y方向上都不相交的全黑子矩形个数)；<br />前两个显然灰常好求，第三个，只要求出每个点左上、右上、左下、右下四个方向里面的全黑子矩形个数，也灰常好求&#8230;&#8230;<br />不过有一个细节：如何求出以某行/列为最下行/最右列的全黑子矩形个数？<br />一种方法是往左/右（或上/下）第一个比它矮的地方不断迭代，但这样遇到阶梯状的会被卡掉；<br />正确方法是找到往左/右（或上/下）第一个比它矮的地方，然后以这里为右下角的全黑子矩形个数=以那个地方为右下角的全黑子矩形个数+这里的高度*两个位置的距离；<br />然后就是严格的O(N<sup>2</sup>)了（不过数据很弱，本沙茶使用会被阶梯状的卡掉的办法也AC了囧）；<br /><br />至此Day1完挂。<br /><br />【Day2】<br />（全DS题什么心态？？？？？？）<br />homework：<br />第一问&#8230;&#8230;是人都会吧囧&#8230;&#8230;<br />第二问&#8230;&#8230;傻眼了囧&#8230;&#8230;<br />其实看到第二问这种不能合并的东东就应该想到分块&#8230;&#8230;这里说一种时间复杂度为O(N<sup>5/3</sup>)的分块方法<br />注意本题的两问都满足区间减性质，即&#8220;A[l1..r1]中关于[l2..r2]范围内的数的结果=A[l1..r1]中关于[0..r2]范围内的数的结果- A[l1..r1]中关于[0..l2-1]范围内的数的结果&#8221;。<br />因此，可以先对[l2..r2]这一维离线，然后按照值递增的顺序逐个加入A数组中的所有元素（一开始A数组为空），每加入一个数，就对l2或r2等于这个数的所有询问计算结果，这样原题就转化为了这个问题：<br />一个长为N的序列，一开始所有位置都为空，现在有两个操作：（1）在某个空位置插入一个数；（2）询问目前某区间内的数的总数，以及不相同的数的总数；<br />这两个问题都可以分块解决：设S1[i][j]和S2[i][j]分别表示目前第i块到第j块中数的总数以及不相同的数的总数，同时维护bool FF[i][j][k]表示第i块到第j块是否出现数k。插入一个数时直接维护S1，根据FF维护S2即可。显然块大小sz应取N<sup>2/3</sup>，总的时间、空间复杂度均为O(N<sup>5/3</sup>)。<br />这样&#8230;&#8230;本题时限10s应该能过了吧囧&#8230;&#8230;但是常数&#8230;&#8230;万恶的常数啊！！！！！（事实上后5个点在本机上都是8.5s左右的，只有第4、5个点T，但在那里不知为什么几乎全T了&#8230;&#8230;）<br /><br />disconnected：<br />这个&#8230;&#8230;本沙茶真心不会搞囧&#8230;&#8230;<br />@drcrow神犇说有一种按询问分块的办法，其思想具体见他今年CTSC的论文&#8230;&#8230;但本沙茶智硬理解不了&#8230;&#8230;<br />求各位神犇解释&#8230;&#8230;<br /><br />diff：<br />（很水的题，很坑爹的常数&#8230;&#8230;本题真是推广SAM的利器&#8230;&#8230;）<br />本题的核心在于算任意两个后缀的LCP之和，其它的很容易推导出来&#8230;&#8230;<br />后缀的LCP，&#8220;正常人&#8221;的第一反应是SA&#8230;&#8230;<br />求出SA及height后，转化为线段树问题&#8230;&#8230;然后就直接搞定了&#8230;&#8230;<br />但是&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />本题N&lt;=500000，时限2s！！！！！！！！！！！！！！！！！！！！！！！！！！！！<br />如果求SA，不管是倍增还是DC3都会T（把SA求出来就T了）<br />因此，正解其实是SAM，把这个串的SAM求出来之后，直接用DFS求次序，再求height&#8230;&#8230;这里的时间复杂度就是线性的了。<br />（WJMZBMR：现在SA早就过时了，要用SAM！！！不，其实SAM也过时了，现在是Suffix BST以及2<sup>K</sup> Substring BST，但考虑到AH太弱了，同情一下，降低一点难度&#8230;&#8230;）<br /><br />至此AHOI Round2完挂。<br />（不过许多人都放水了囧&#8230;&#8230;他们说我去年滚粗，太可怜了，要照顾我&#8230;&#8230;于是我这样的弱智就A队了&#8230;&#8230;）<br />（HSAAHNU进了6个&#8230;&#8230;太可怕了，坐等NOI组团虐场&#8230;&#8230;）<br /></div><img src ="http://www.cppblog.com/MatoNo1/aggbug/200747.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/MatoNo1/" target="_blank">Mato_No1</a> 2013-06-17 22:37 <a href="http://www.cppblog.com/MatoNo1/archive/2013/06/17/200747.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AHOI2013 Round1 题解&amp;&amp;总结</title><link>http://www.cppblog.com/MatoNo1/archive/2013/05/18/200374.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Sat, 18 May 2013 09:38:00 GMT</pubDate><guid>http://www.cppblog.com/MatoNo1/archive/2013/05/18/200374.html</guid><wfw:comment>http://www.cppblog.com/MatoNo1/comments/200374.html</wfw:comment><comments>http://www.cppblog.com/MatoNo1/archive/2013/05/18/200374.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/MatoNo1/comments/commentRss/200374.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/MatoNo1/services/trackbacks/200374.html</trackback:ping><description><![CDATA[<div>（首先声明一下，今年AHOI R1的题==JSOI R3 Day1的题）<br />【题解】<br />sport:<br />首先很容易证明，最优方案必然是左边都是-，右边都是+（从样例也可以看出来囧）&#8230;&#8230;<br />因此问题转化为了第几次开始+，可以使得开始+的时候，目标元素的位置最左&#8230;&#8230;<br />注意到排队的过程实际上是个冒泡&#8230;&#8230;因此本题的关键在于发掘出冒泡的性质囧&#8230;&#8230;<br />设最初的序列为A[0..N-1]，目标元素为A[pos]。设S[0]为排在A[pos]之左的比A[pos]大的元素的个数（因为一开始排在A[pos]之左的且&lt;=A[pos]的元素，不管肿么搞都一直在目标元素之左，不管它们了囧&#8230;&#8230;），然后，考察所有一开始排在A[pos]之右的，比A[pos]小（注意是&lt;A[pos]，不是&lt;=）的所有元素，设它们之间的间隔分别为S[1]、S[2]、S[3]&#8230;&#8230;（具体见图，其中S[1]为A[pos]和第一个比A[pos]小的元素之间的间隔）<br /><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/matono1/描述所用图片/AHOI2013_R1_sport.JPG" width="439" height="72" /><br />然后来审视一下整个冒泡的过程。一开始，必然是将目标元素左边的一个比目标元素大的元素移到右边去，在目标元素右边它可能会停下来，但紧接着必然是一个值更大的元素继续往右移，最终的效果等价于将目标元素左边的一个比目标元素大的元素&#8220;移出去&#8221;了（即移到了最右边的比目标元素小的元素的右边），也就是S[0]减了1，而S[1]、S[2]&#8230;&#8230;都没变，这个过程显然只能持续S[0]次，目标元素左边比它大的元素就全部移出去，此时目标元素到达了它&#8220;可能到达&#8221;的最左位置。<br />接着，目标元素和右边第一个比它小的元素（即图中的A[i1]）之间的，比目标元素大的那些元素将被依次的移出去，也就是S[1]不断减1，而S[2]及后面的都没变。这一过程会持续S[1]次，目标元素就和A[i1]靠在一起了（注意，在这个过程中，目标元素的位置是不会变的）。<br />如果此时继续冒泡，则目标元素就会和A[i1]交换，右移一个位置，并且就从这次冒泡开始，S[2]不断减1，减到0为止，接着目标元素和A[i2]交换，右移一个位置，S[3]不断减1&#8230;&#8230;直到最后一个S[]值也减到0后，目标元素到达它的目标位置。<br />也就是，设&#8220;第i阶段&#8221;为S[i]值减少的这个阶段，则在第0阶段，目标元素会不断左移，显然不用+，第1阶段，目标元素不动，也不用+，但从第2阶段开始，在每阶段的第一次冒泡时，目标元素都会向右移一个位置。因此，开始+的时候，必然是第x（x&gt;=2）阶段的开始的那次。由于最多只能+ K次，因此可能的最左位置就是满足N-1-&#8721;(0&lt;=j&lt;x)S[j] &lt;=K的最小的x值减2，加上一开始就在目标元素之左的，且值不大于目标元素的元素个数（它们必然在目标元素之左）。注意特殊情况：x&lt;2（此时当成x=2处理），或者x不存在（全是-）。<br />因此，本题就是预处理求出所有S之后，扫一遍得出最小的x值就行了，O(N)。<br />当然，二分答案+暴力判断可以得50，有神犇说二分答案之后可以在O(N)时间内判断，从而O(NlogN)解决，我太弱了，完全搞不懂囧&#8230;&#8230;（Orz！！）<br /><br />mole：<br />首先，一个很重要的事实就是，&#8220;整个过程中左手所在的位置严格小于右手&#8221;其实是一个废条件！！因为如果左右手交叉了，必然是左手试图去打靠右的一个，而右手试图去打靠左的一个，此时，让它们交换，则两只手移动的距离都变小，方案仍然合法，且更优（我太弱了，当时就是在这里想抽了很久，以至于木有做这题&#8230;&#8230;后来才知道这题很水&#8230;&#8230;真悲剧！！！）<br />接下来就变成了一个全局统筹的问题，可以用网络流解决：每个地鼠i拆成两个点：入点i'、出点i''，中间连一条容量为1（表示只能打一次），费用为它的得分的边，两只手开始的位置也当成有地鼠，只不过得分为0而已。如果某只手在打完第i个地鼠后能接着去打第j个地鼠，就连边&lt;i'', j'&gt;，容量1，费用0。s往表示两只手开始的两个点的入点连一条容量为1，费用为0的边，每个出点往T连一条容量为1，费用为0的边。求这个图的最大费用最大流即可。<br />当然，用O(N<sup>3</sup>)的DP也可以得到至少60分，如果卡的好的话可能有80以上囧&#8230;&#8230;<br /><br />bus：<br />裸的数据结构题，用一坨Splay Tree维护即可，唯一要注意的就是链可以翻转，因此要rev标记&#8230;&#8230;<br />还是不会搞的可以去做ZJOI2012 Day2的某题&#8230;&#8230;<br />这题在数据结构题中还是比较好写的&#8230;&#8230;值得吐槽的是它的对拍很难写&#8230;&#8230;本沙茶写正解用了50min，写对拍用了75min&#8230;&#8230;<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />【总结 &amp;&amp; 一些闲扯】<br />（1）（Orz @sunzhouyi）<br />&#8220;要想滚粗： 
<div><span style="white-space: pre"></span>0.仔细看错或者记错题。</div>
<div><span style="white-space: pre"></span>1.选对不可做题。</div>
<div><span style="white-space: pre"></span>2.思考坑爹题[鉴于&#8216;坑爹&#8217;一词在AH的特殊含义，建议这一点改为&#8220;思考废条件怎么处理&#8221;]。</div>
<div><span style="white-space: pre"></span>3.认真写自己不会的东西。</div>
<div><span style="white-space: pre"></span>4.最后还不写暴力分。&#8221;<br />本沙茶中了其中的三点，因此悲剧了&#8230;&#8230;<br />（2）<span style="color: red"><strong>热烈庆祝今年的题目不再坑爹了！！！！！</strong></span><span style="color: red"><strong>！</strong></span>（因为用的是JSOI的题，bus还抄袭了ZJOI&#8230;&#8230;）<br />（3）这次的题目&#8230;&#8230;要么是难想、好写（sport代码只有1K多），要么是好想、较难写，但还可以写的完的（指bus，和BZOJ上最近的那些数据结构相比真是太人道了&#8230;&#8230;）<br />（4）要善于发掘题目的本质，特别是一些隐含的最优性质（比如mole的那个废条件为什么废）；<br />（5）遇到想了很久想不出的题，一定要换一个方向去想，因为很可能是一开始的方向疵了；<br />（6）对于代码量较大的题（如数据结构题），到底写不写是要看情况的，灵活掌握；<br /><br />一些闲扯：<br />（1）本沙茶所在的考场几乎全是神犇，就我一个沙茶&#8230;&#8230;于是被虐傻了&#8230;&#8230;<br />（2）比赛时看到对面的一个人在喝&#8220;和其正&#8221;&#8230;&#8230;瞬间吓傻了&#8230;&#8230;（话说肿么木有看到喝阿华田的囧&#8230;&#8230;）<br />（3）昨天试机的时候，被Atbiter虐了半天，一开始肿么配置都是&#8220;找不到答案文件&#8221;&#8230;&#8230;后来才发现Atbiter已经改版了，players下面的第一层文件夹应该是考试场数编号（Day1、Day2&#8230;&#8230;）；<br />（4）试机的时候发现鼠标是坏的，后来才知道这个考场有6个鼠标坏了，3个键盘坏了，2个系统时间显示错误&#8230;&#8230;<br />（5）总之这次挂惨了，不过前30应该能进，重点是Round2，加油！！我要复仇！！<br /></div></div><img src ="http://www.cppblog.com/MatoNo1/aggbug/200374.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/MatoNo1/" target="_blank">Mato_No1</a> 2013-05-18 17:38 <a href="http://www.cppblog.com/MatoNo1/archive/2013/05/18/200374.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AHOI2013 大致的规则出来了</title><link>http://www.cppblog.com/MatoNo1/archive/2012/09/21/191533.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Fri, 21 Sep 2012 13:34:00 GMT</pubDate><guid>http://www.cppblog.com/MatoNo1/archive/2012/09/21/191533.html</guid><wfw:comment>http://www.cppblog.com/MatoNo1/comments/191533.html</wfw:comment><comments>http://www.cppblog.com/MatoNo1/archive/2012/09/21/191533.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/MatoNo1/comments/commentRss/191533.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/MatoNo1/services/trackbacks/191533.html</trackback:ping><description><![CDATA[<a title="相关链接" href="http://www.ahjyzb.com/list_index.php?menu=content&amp;id=10480">相关链接</a><br /><br />由此看来，省队（准确来说是&#8220;省集训队&#8221;）的压力减小很多了囧&#8230;&#8230;因为即使省选题目再坑爹，也有NOIP的40%垫着&#8230;&#8230;<br />显然，NOIP必须得高分，甩开别人，甩得越远越好，这样才能在省集训队的选拔中占据优势&#8230;&#8230;<br />不过，进了省集训队之后又肿么选，就不知道了&#8230;&#8230;<br /><br />而且估计明年的省选应该木有这么坑爹了囧&#8230;&#8230;<br />其实&#8230;&#8230;最近发现即使是AHOI2012的后3题，只要会各种搜索+近似也是可以搞到很多分的&#8230;&#8230;至少加起来100分木问题（总分200就A队了）&#8230;&#8230;<br /><br />所以，<span style="color: red"><strong>实力终究是硬道理！！！！！！！！！！！！！！！！！！！！！！！！！！！！</strong></span><br /><br />我要进省队！！！！<br />我要进国家集训队！！！！<br /><img src ="http://www.cppblog.com/MatoNo1/aggbug/191533.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/MatoNo1/" target="_blank">Mato_No1</a> 2012-09-21 21:34 <a href="http://www.cppblog.com/MatoNo1/archive/2012/09/21/191533.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AHOI2013 期待中……</title><link>http://www.cppblog.com/MatoNo1/archive/2012/08/05/186303.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Sat, 04 Aug 2012 16:32:00 GMT</pubDate><guid>http://www.cppblog.com/MatoNo1/archive/2012/08/05/186303.html</guid><wfw:comment>http://www.cppblog.com/MatoNo1/comments/186303.html</wfw:comment><comments>http://www.cppblog.com/MatoNo1/archive/2012/08/05/186303.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/MatoNo1/comments/commentRss/186303.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/MatoNo1/services/trackbacks/186303.html</trackback:ping><description><![CDATA[<a title="相关链接0" href="http://tieba.baidu.com/f?kz=1614015738">相关链接0</a><br /><a title="相关链接1" href="http://tieba.baidu.com/p/1614320034">相关链接1</a><br /><br />NOI2012结束了，对本沙茶来说就是鸡肋之战，因为不管得多少分都木有用，只能得到像废纸一样的成绩证明（其实就连这个，本沙茶都木有拿到囧）<br />而AHOI2012选出来的安徽省队，成绩史上最差，正式选手首次Au、Ag都木有，在忽略团体对抗赛的情况下，团体分全场Rank20，东部倒数第二&#8230;&#8230;<br />唯一值得庆幸的是团体对抗赛得了Rank4，而且是在决赛时RP耗尽导致的&#8230;&#8230;<br /><br />真真切切希望：<br />（1）2012~2013赛季中，自己的水平能快速提高，早日脱菜；<br /><strike>（2）NOIP2012 AH 1=分数线不低于全国划线；<br /></strike>（这个梦想已经破灭了&#8230;&#8230;唯一能希望的就是CCF NOI2013省队名额改革，要是真改不了就用尽全力挤进前4吧囧&#8230;&#8230;毕竟2011年本沙茶都干出过这个，2013年应该也可以囧）<br />（3）<span style="color: red"><strong>AHOI2013不要再出像今年这样的题了，至少要保证每题都有正解、数据范围不骗人；</strong></span><br />（4）NOI2013上，AH今年的悲剧不要重演，团体分至少进Rank12&#8230;&#8230;<br /><br />其它就木有神马可说的了囧。<br /><br />（本沙茶曾经在网络上消失了很长一段时间，现在回来了，原来那个帖子删除） <img src ="http://www.cppblog.com/MatoNo1/aggbug/186303.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/MatoNo1/" target="_blank">Mato_No1</a> 2012-08-05 00:32 <a href="http://www.cppblog.com/MatoNo1/archive/2012/08/05/186303.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AHOI2007 题解</title><link>http://www.cppblog.com/MatoNo1/archive/2012/05/04/173607.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Fri, 04 May 2012 10:00:00 GMT</pubDate><guid>http://www.cppblog.com/MatoNo1/archive/2012/05/04/173607.html</guid><wfw:comment>http://www.cppblog.com/MatoNo1/comments/173607.html</wfw:comment><comments>http://www.cppblog.com/MatoNo1/archive/2012/05/04/173607.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/MatoNo1/comments/commentRss/173607.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/MatoNo1/services/trackbacks/173607.html</trackback:ping><description><![CDATA[【注：本沙茶完成AHOI2007的题目用了3年多&#8230;&#8230;因为6道题中，有2题是2009年AC的，1题是2010年AC的，剩下3题是2012年AC的&#8230;&#8230;】<br /><br />box:<br />要求x<sup>2</sup>=kn+1（k为整数），即(x+1)(x-1)=kn。因为(x+1)和(x-1)所可能具有的共同的质因数只有2，因此可以分为两种情况：（1）x是奇数，且n是4的倍数，此时可以将(x+1)和(x-1)都除以2，n除以4之后，转化为(x+1)/2或(x-1)/2是n/4的倍数，然后直接求解；（2）其它情况：此时必然是(x+1)或(x-1)是n的倍数，可以直接求解。注意需要特判一下x=0的情况；<br /><br />door：<br />求逆矩阵的问题。方法：设置N*N的矩阵A和B，A初始为待求逆的矩阵，B为单位矩阵，然后，不断地对A和B同时实施相同的初等行变换，直到将A变成单位矩阵为止，此时B就是A的逆矩阵，若无论如何也不能将A变成单位矩阵，则A无逆矩阵。<br />初等行变换有3种：（1）两行互换；（2）将一行整体乘以一个非0常数；（3）将一行加到另一行上。<br />具体操作：类似于高斯消元。第一步，i从0到n-1，在A的第i到(n-1)行中找到一个第i列不为0的（若找不到则A无逆矩阵），并将其与第i行互换（变换1），然后，对第i行后面所有第i列不为0的，将其整行乘以一个非0常数（变换2），使得其第i列的值刚好是-A[i][i]，并将第i行加到这一行上（变换3）使得其第i列变为0，这样一直下去，可以把A的下三角全部变为0；第二步，i从n-1到0，对于第i行第(i+1)列及其以后的每个数，若有不为0的，将其乘上一个常数（变换2）使得这个数变为-1，再用后面的已经处理好的单位矩阵对应行加到第i行上（变换3），将这个数变为0，这样一直到最后一列为止，最后，要把第i行乘上一个常数（变换2）使得A[i][i]=1，这样第i行就处理好了，这样一直下去，直到所有的行都处理好为止。<br /><br />light：<br />首先对这个字符串A[0..n-1]进行自身exKMP，求出nx数组，nx[i]表示A[i..n-1]与A[0..n-1]的LCP长度。<br />然后，点灯器的长度为p可行的充要条件是：（1）nx[n-p]==p；（2）对于整个nx数组，取出其所有大于等于p的元素，则相邻两个元素的距离（下标之差）都不超过p。<br />对于第（2）个条件，只要用一个线段树维护最大距离就可以了，枚举p的时候正、逆序均可，推荐逆序，这样实际上等于不断插入元素，比删除元素要方便。<br /><br />rock：<br />超级大水题。只要把矩阵中所有的0变成-1，再求最大子矩阵就行了。<br /><br />redcross：<br />求01矩阵中最大的某种性质的子矩阵类的题目。最暴力的做法显然是13个数组（原始数组+上下左右延伸0的长度+上下左右延伸1的长度+左上左下右上右下延伸的0正方形的边长），如果把上下左右延伸0和1的长度进行合并可以减少到9个数组，但这样对于这种如此卡常数的题目还是会TLE的。其实，可以换一种思考方式，最后只用6个数组（包括原始数组）就解决了问题&#8230;&#8230;至于这个是肿么搞的，现在不能说，以后的某一天再说&#8230;&#8230;<br />另外<a title="这里" href="http://www.rqnoj.cn/Problem_BestSolution.asp?PID=300">这里</a>的最优解排序&#8230;&#8230;发现有惊人的地方么囧&#8230;&#8230;<br /><br />maze：<br />由于可以随便走，N&lt;=10，因此可以枚举前5步的走法和后面5步的走法（其实全是一样的，枚举一次就行了，只是存储方式不同），把能得到的所有权值和分最后到达位置（前5步）和开始位置（后5步）存在数组里，然后就是二分查找了囧&#8230;&#8230;至于N&lt;10的情况就少几步枚举了囧。其实还是比较难写的，本沙茶2009年写这题的时候写了整整一晚上，当然这或许与本沙茶当时太太太太太&#8230;&#8230;弱了有关（当然现在仍然弱）<br /> <img src ="http://www.cppblog.com/MatoNo1/aggbug/173607.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/MatoNo1/" target="_blank">Mato_No1</a> 2012-05-04 18:00 <a href="http://www.cppblog.com/MatoNo1/archive/2012/05/04/173607.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Splay Tree处理区间问题的几道好题及总结</title><link>http://www.cppblog.com/MatoNo1/archive/2011/06/25/149425.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Sat, 25 Jun 2011 03:21:00 GMT</pubDate><guid>http://www.cppblog.com/MatoNo1/archive/2011/06/25/149425.html</guid><wfw:comment>http://www.cppblog.com/MatoNo1/comments/149425.html</wfw:comment><comments>http://www.cppblog.com/MatoNo1/archive/2011/06/25/149425.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/MatoNo1/comments/commentRss/149425.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/MatoNo1/services/trackbacks/149425.html</trackback:ping><description><![CDATA[<div>（1）Robotic Sort（<a title="HDU1890" href="http://acm.hdu.edu.cn/showproblem.php?pid=1890">HDU1890</a>、<a title="ZJU2985" href="http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2985">ZJU2985</a>）<br />本题主要考察的是对此类问题，序列中给定值的索引问题。<br />当Splay Tree用来处理一个序列的时候，其关键字就是序列中元素的下标，而不是元素的值。这样，如果要查找序列中给定的值的位置（假设序列中任意两个元素的值不相等）看起来就无法实现。其实也是有办法实现的：因为元素在树中的<span style="color: red"><strong>下标</strong></span>是永远不变的！也就是，设这个序列为A，如果A[i]在插入Splay Tree时的下标为j，那么在A[i]被删除之前，其下标一直是j，永远不会变（注意元素在序列中的下标和在树中的下标是不同的）。利用这一性质可以解决给定值的索引问题。<br />对于本题，每次将从序列中第i小的元素到序列中第i个元素（这里假定元素下标是从1开始的，而不是从0开始）之间的所有元素反转，并输出第i小的元素在反转之前的在序列中的下标。设B[i]为第i小的数的<span style="color: #ff0000"><strong>初始位置</strong></span>，S[i]为<span style="color: #ff0000"><strong>初始位置</strong></span>在第i位的元素的下标，B[i]和S[i]都可以通过预处理得到。然后，每次交换前，求出S[B[i]]在树中的排名（基本操作），再减1（因为有边界结点）就是该元素目前的位置，而序列中第i个元素就是树中第(i+1)小的元素，再执行交换即可。<br />不过需要千万注意的是本题的标记问题，在求S[B[i]]在树中的排名时，有可能其祖先结点上有标记，需要先遍历其所有的祖先结点，再逆向下放标记（标记只能自顶向下传）。另外在交换的时候需要求出S[B[i]]的后继，在求后继的过程中需要查找，此时千万别忘了下放标记（总的说，凡是有查找的地方，就有dm）<br /><a title="代码" href="http://www.ideone.com/NRqFR">代码</a>（本沙茶太弱了，是抄别人的，因此其算法和上面总结的可能有差别，神犇不要鄙视）</div><br />（2）SuperMemo（<a title="PKU3580" href="http://poj.org/problem?id=3580">PKU3580</a>）<br />本题的6个操作中，add、reverse、insert、delete、min都不难搞，而revolve操作需要涉及到区间交换。<br />可以发现，所谓的旋转其实就是交换两个相邻区间，这对于功能极强的Splay Tree来说根本不难搞。<br />设这两个相邻区间为[x, y]与[y+1, z]，假设它们均非空（也就是x&lt;=y&lt;z，因为若其中至少有一个区间是空区间，则交换没有意义），先找到树中x的前趋P与z的后继S（这里x、z等指的都是对应的结点，下同），将P伸展到根、将S伸展到根的右子结点处，则S的左子树就表示区间[x, z]。然后，设S的左子树的根结点（也就是S的左子结点）为N，在这棵子树中找到第1小的结点P0与第(y-x+2)小的结点S0（这需要涉及到找子树内第K小的操作，只要把找整棵树第K小的操作的root改为N即可），它们分别表示x与(y+1)，这样将P0伸展到N处，将S0伸展到N的右子结点处，显然P0无左子树，S0的左子树T1表示区间[x+1, y]，S0的右子树T2表示区间[y+2, z]。然后，先将S0从P0的右子结点移动到P0的左子结点，再将T1作为P0的右子树（注意移动是两步：插入和删除）。这样整棵子树的中序遍历结果变成了S0-&gt;T2-&gt;P0-&gt;T1，也就是[y+1, z]&#8746;[x, y]。<br />另外本题的标记有点难搞，只需注意rev是逆向标记，以及查找与dm共存就行了。<br /><a title="代码" href="http://www.ideone.com/HPSvO">代码</a><br />（3）Play with Chain(<a title="HDU3487" href="http://acm.hdu.edu.cn/showproblem.php?pid=3487">HDU3487</a>)<br />这个米有神马好说的，里面的操作在SuperMemo里都有；<br /><a title="代码" href="http://www.ideone.com/E4EXT">代码</a><br />（4）<a title="AHOI2006 文本编辑器(editor)" href="http://mail.bashu.cn:8080/BSoiOnline/showproblem?problem_id=2455">AHOI2006 文本编辑器(editor)</a><br />这题在这一类题里面算水的。对于光标，只要用一个值来维护就行了。<br />另外注意本题极为猥琐的2点（题目中米有说明）：一是最初的文本并不是空的，而是有一个空格；二是执行GET操作时光标可能位于文本末尾，此时应输出空格；<br /><a title="代码" href="http://www.ideone.com/dUjKz">代码</a><br />（5）HFTSC2011 高精度计算器(apc)，题目见<a title="这个帖子" href="http://tieba.baidu.com/f?kz=1039909717">这个帖子</a>；<br />这题反映出了一个很囧的问题：有些信息会被rev整体破坏。<br />本题中的操作都是常见操作，但是本题所需要维护的信息却不是那么容易维护。本题要求维护一棵子树中所有结点所表示的元素序列（中序遍历结果）模一个指定的M的值。设F[i]为R^i mod M的值（这里R是进制，也就是题目中的K），则有：<br />T[x].mod = (T[T[x].c[0]].mod * F[T[T[x].c[1]].sz + 1] + T[x].v * F[T[T[x].c[1]].sz] + T[T[x].c[1]].mod) % M;<br />这个式子其实是很好理解的。<br />关键是，本题的猥琐之处并不在此。注意本题的rev操作，它会整体改变树中所有结点所记录的mod值，这时，如果再用上面这个式子来维护T[x].mod，就会出错，因为此时引用到的T[T[x].c[0]].mod和T[T[x].c[1]].mod都是过时的。解决这一问题只有一种方法：记录&#8220;逆mod&#8221;(rmod)，意思是将整个元素序列反转后的mod，即：<br />T[x].rmod = (T[T[x].c[1]].rmod * F[T[T[x].c[0]].sz + 1] + T[x].v * F[T[T[x].c[0]].sz] + T[T[x].c[0]].rmod) % M;<br />这样，在反转某序列的时候，直接将根结点的mod值和rmod值交换就行了。<br />像mod这样会被反转操作整体破坏的信息还有很多，比如NOI2005 sequence里面的lmax和rmax。如果真的遇到这类信息，只有采用上面的方法。<br />另外，本题第6、9、10个点有误。<br /><a title="代码" href="http://www.ideone.com/FK4nQ">代码</a><br /><br />现在Splay Tree差不多弄完了，接下来还有N多知名的、不知名的高级数据结构&#8230;&#8230;时间MS有些不够用了囧&#8230;&#8230;<br /> <img src ="http://www.cppblog.com/MatoNo1/aggbug/149425.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/MatoNo1/" target="_blank">Mato_No1</a> 2011-06-25 11:21 <a href="http://www.cppblog.com/MatoNo1/archive/2011/06/25/149425.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AHOI2006 基因匹配(match)</title><link>http://www.cppblog.com/MatoNo1/archive/2011/03/19/142240.html</link><dc:creator>Mato_No1</dc:creator><author>Mato_No1</author><pubDate>Sat, 19 Mar 2011 14:38:00 GMT</pubDate><guid>http://www.cppblog.com/MatoNo1/archive/2011/03/19/142240.html</guid><wfw:comment>http://www.cppblog.com/MatoNo1/comments/142240.html</wfw:comment><comments>http://www.cppblog.com/MatoNo1/archive/2011/03/19/142240.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/MatoNo1/comments/commentRss/142240.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/MatoNo1/services/trackbacks/142240.html</trackback:ping><description><![CDATA[依照CLJ神犇的指示，最近本沙茶决定开始被数据结构题虐&#8230;&#8230;先找来了省内的一道题（就是这道囧）&#8230;&#8230;<br><br>题目大意：求两个长度为5N的序列的最长公共子序列长度，在两个序列中，整数1~N分别都出现5次。1&lt;=N&lt;=20000。<br><br>【注：本沙茶一开始用线段树的，后来在看了CLJ神犇的标程（Orz！！）之后终于明白了树状数组解法囧&#8230;&#8230;】<br><br>LCS问题的朴素时间复杂度为O(NM)。对于本题显然需要优化。<br>观察LCS的转移方程：<br>F[i][j] = F[i-1][j-1]+1（当A[i]==B[j]时）<br>F[i][j] = max{F[i-1][j], F[i][j-1]}（当A[i]!=B[j]时）<br><br>可以将F用滚动数组来表示，即设F'为上阶段的F（即F[i-1]），则本阶段的F（即F[i]）可以由F'求得：<br>F[j] = F'[j-1]+1（当A[i]==B[j]时）<br>F[j] = max{F'[j], F[j-1]}（当A[i]!=B[j]时）<br><br>进一步，这个F'其实都不用记录，只需在每一阶段更新一遍F即可：<br>F[j] = F[j-1]+1（当A[i]==B[j]时）<br>F[j] = max{F[j], F[j-1]}（当A[i]!=B[j]时）<br>不过需要逆序更新（保证F[j-1]是上一阶段的而不是本阶段的），这与01背包有点像。<br><br>由题意可以发现，A[i]==B[j]的出现次数极少，在每阶段中只会出现5次！我们可以预先求出这5个地方的值，然后对于其它的F[j]，其在本阶段的值其实就是它前面的最大值（max{F[1..j-1]}），又因为我们最后只需知道F[N']（N'=5N，即序列长度）即可，故可设计出以下算法：<br>一开始F[1..N]均为0，然后将以下内容执行N'次，第i次：<br>（1）求出B序列中与A[i]相等的5个元素的位置，设为S[1..5]；<br>（2）依次更新F[S[5..1]]，每个都更新为它前面的最大值加1（很容易知道为神马），其它的值暂时不管；<br><br>N'次执行完后，整个序列中的最大值就是F[N']的值。由于这个算法中出现的主要操作是改动一个指定位置元素的值和找一个前缀区间中的最大值，因此可以采用树状数组，时间复杂度O(NlogN）（线段树必TLE）。<br><br>【总结：在本题中使用了一种&#8220;推迟更新&#8221;的方法，即需要更新一个值时，先暂时不理它，等到需要引用到它的时候再更新。这种方法最常见的应用就是线段树的结点标记。不过要注意的是，如果该值的推迟更新会对它后面要更新的值带来问题（也就是，这些后更新的值需要引用该值的新值），就不能使用这种方法。在本题中，其它位置的值的改变只与这5个特殊的位置有关，与其它因素无关，故可以使用这种方法。】<br>
<img src ="http://www.cppblog.com/MatoNo1/aggbug/142240.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/MatoNo1/" target="_blank">Mato_No1</a> 2011-03-19 22:38 <a href="http://www.cppblog.com/MatoNo1/archive/2011/03/19/142240.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>