• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            相關鏈接0
            相關鏈接1

            NOI2012結束了,對本沙茶來說就是雞肋之戰,因為不管得多少分都木有用,只能得到像廢紙一樣的成績證明(其實就連這個,本沙茶都木有拿到囧)
            而AHOI2012選出來的安徽省隊,成績史上最差,正式選手首次Au、Ag都木有,在忽略團體對抗賽的情況下,團體分全場Rank20,東部倒數第二……
            唯一值得慶幸的是團體對抗賽得了Rank4,而且是在決賽時RP耗盡導致的……

            真真切切希望:
            (1)2012~2013賽季中,自己的水平能快速提高,早日脫菜;
            (2)NOIP2012 AH 1=分數線不低于全國劃線;
            (這個夢想已經破滅了……唯一能希望的就是CCF NOI2013省隊名額改革,要是真改不了就用盡全力擠進前4吧囧……畢竟2011年本沙茶都干出過這個,2013年應該也可以囧)
            (3)AHOI2013不要再出像今年這樣的題了,至少要保證每題都有正解、數據范圍不騙人;
            (4)NOI2013上,AH今年的悲劇不要重演,團體分至少進Rank12……

            其它就木有神馬可說的了囧。

            (本沙茶曾經在網絡上消失了很長一段時間,現在回來了,原來那個帖子刪除)

            posted @ 2012-08-05 00:32 Mato_No1 閱讀(970) | 評論 (7)編輯 收藏

                 摘要: 【異或(XOR)運算由于與“奇偶性”密切相關,經常出現在有關奇偶性和二進制的題目中】很多異或問題都要涉及到解異或方程組,因此首先要搞懂異或方程組的解法。(1)異或方程組的格式(設有n個未知數,m個方程):a11*x1 XOR a12*x2 XOR ... XOR a1n*xn = b1a21*x1 XOR a22*x2 XOR ... XOR a2n*xn = b2R...  閱讀全文

            posted @ 2012-05-20 10:17 Mato_No1 閱讀(10257) | 評論 (4)編輯 收藏

            【dispatching】
            (這題國內數據極弱,暴力能80,下面的解法1,平衡樹即使用Splay Tree實現都能AC)
            枚舉管理者所在的結點,然后在這個結點及其所有后代中找到權值前K小的,使得它們的權值和不超過限制,要求求出K的最大值。
            解法1:將每個結點及其所有后代的權值存在一個平衡樹里,然后,對于每個結點,若不是葉結點,就將其所有的子樹中,找到最大的那棵子樹,它所表示的平衡樹不動,將其它的子樹表示的平衡樹上的所有結點強行拆開,并插入到這個子樹表示的平衡樹中(這叫啟發式合并),別忘了將該結點本身也合并到這棵平衡樹里。合并好了以后,通過每個點記錄的sum(下面說明),用類似于求結點排名的方法,就可以求出K的最大值了。
            容易證明,這樣合并的話,在整個過程中插入的次數是O(NlogN)的,加上平衡樹插入本身的O(logN),總的時間復雜度為O(Nlog2N)。
            具體實現起來有一些技巧:
            (1)可以發現,在合并過程中,各個點本身并沒有變,而只是它們之間的關系發生了變化(從不在同一棵樹上變成在同一棵樹上了),因此為了節省空間,可以預先將所有的結點建好,每個結點除了自身權值以外還記錄mul(初始為1)、sz(初始為1)、sz0(初始為1)、sum(初始等于權值)等信息,其中mul為重復次數,sz為考慮mul情況下的樹的大小,sz0為不考慮mul的情況下的樹的大小(也就是實際結點個數),sum表示樹上所有結點的總權值(這個當然要考慮mul了)。之所以維護sz0,是因為每次可以通過找到sz0最大的子樹不動來加速。插入的操作是void ins(int r, int No),表示將結點No(是結點不是值)插入到以r為根的子樹里,注意這個結點No的mul可能大于1,因此在插入后維護的時候需要注意;
            (2)由于在過程中會同時有多棵平衡樹存在,因此每個點還需要記錄一個額外的域rf,rf=-1表示該結點不是任何一棵平衡樹的根結點,rf>=0表示該結點是原樹中編號為rf的結點表示的平衡樹的根結點,同時記錄root[i]表示結點i表示的平衡樹的根結點編號,這樣就可以很方便地實現樹內外的對接(注意這兩個值的維護,尤其是將結點i本身合并到平衡樹里的時候,別忘了把root[i]改掉)。
            解法2(正解):合并的時候使用可并堆(用左偏樹或斜堆實現),時間復雜度O(NlogN)。

            【guard】
            (這題其實很容易想到網絡流的話說……不過仔細研究一下就可以發現,由于報告上來的只是某一個區間內有木有人,而不是有幾個人,因此無法用網絡流的流量平衡來表示)
            首先,某些區間報告木有人,這些區間內的點肯定不符合要求了,可以將它們刪掉,然后對于剩下的(可能是若干段)區間,合并起來,對結點從左到右重新編號(這一步可以用線段樹,也可以排序后直接掃描,見這里,本沙茶比賽時為了省事直接上線段樹了),然后就只需要考慮那些報告有人的區間了囧……當然,這些區間的端點也是要對應地重新編號的,編號完了以后,將所有包含別的區間的區間刪去(因為它們的存在木有意義),方法:對于所有重編號后的區間,將其按照先左端點遞增,后右端點遞減排序,然后設置一個棧,保證棧中的區間左右端點均嚴格遞增,按照排序之后的順序掃描每個區間,每次一個新區間入棧時,棧頂所有右端點大于等于這個新區間右端點的區間出棧,再將新區間入棧,這樣最后棧中的區間就是保留下來的區間了囧……而且已經排序……
            然后,如果問題是求至少要多少個人的話,就是一個經典的貪心模型了,掃描排序后的區間,如果一個區間內還木有任何人,就在它的右端點處放一個人。顯然,除了這些放了人的區間的右端點之外,其余的點肯定都不是必須放人的(因為現在已經有一個方案使它們不放人了)。現在的問題是,這些右端點處是否必須放人。
            設F[i]為第i個區間及其之后的區間當中,若要每個區間內都有人,至少要幾個人。若第i個區間的右端點不小于最后一個區間的左端點,則F[i]=1(在第i個區間右端點放一個人即可),否則,找到最小的j,使得第i個區間的右端點小于第j個區間的左端點(這個顯然可以二分查找得到),則F[i]=F[j]+1。這樣從后到前推一遍即可。然后,再從前到后,按照上面的貪心算法的流程掃一遍,如果遇到第i個區間的右端點需要放人:若第i個區間的長度為1,顯然這里必須放人,否則嘗試在第i個區間的倒數第2個位置(即右端點之前的那個位置)放人,而右端點不放人(可以證明,不會后來又把這個右端點這里放上人的),類似用二分查找的方式找到這個j,然后看一下(_F + F[j] + 1)(_F為第i個區間前面放人個數)是否大于K,若大于K,則第i個區間的右端點必須放人,否則不必須放人。
            此外還有兩種特殊情況,一是M=0的時候在去包含的時候要特判一下(其實這時可以直接特判,若N=K,則所有的地方都必須放人,否則就是-1);二是,如果去掉那些肯定木有人的點后,剩下的點的個數剛好等于K(不可能小于K的,因為肯定有解),則不用貪心了,剩下所有的地方肯定都必須放人。
            總時間復雜度O(NlogN + MlogM);
            這里千萬要注意的一點是,應該先將所有區間重編號再去包含,而不應該先去包含再重編號!!!因為可能有兩個區間本來是不包含的,但重編號以后,包含了。(本沙茶比賽的時候就是這里木有注意到,跪了3個點,杯具了)

            【kunai】
            40分的暴力做法:枚舉兩個動點,求出它們是否會相撞以及相撞的時間,然后將所有相撞事件按照時間排序,掃描排序后的每個事件,如果相撞的兩個動點都還在,就將它們消去,然后可以求出每個動點移動的距離,求一下并集(線段樹)即可;(本沙茶當時主要是實在木有時間寫這題了,因此連暴力都木有寫)
            AC做法:很明顯,一個動點一旦被消去,就不會再次出現了,因此對于每一個點,只需要找到最先和這個點相撞的點即可。顯然能夠相撞的兩個點必然位于同一行/列/對角線上且方向滿足一定限制(其實一共只有6種情況:同一行一種,同一列一種,同一左上右下對角線兩種,同一右上左下對角線兩種)。因此,枚舉這6種情況,直接用掃描法得到最先與它相撞的動點,取相撞時間最小的那個即可,如果都找不到,這個點就是永存的。這樣相撞事件的總數就減少到了O(N)級別,總時間復雜度就是O(NlogN)。
            注意:有可能在同一時間有多個動點在同一位置相撞,因此,對于同時發生的相撞事件,應該將它們一起處理,涉及到的點一起消去。

            posted @ 2012-05-12 21:41 Mato_No1 閱讀(2915) | 評論 (6)編輯 收藏

            【網絡流問題可以說是OI中最靈活的問題之一了,建模方法很多,但還是有一定規律的囧……當然,由于本沙茶做題暫時還比較少,可能這里總結的東東只是網絡流建模技巧的一小部分,希望各位題海神犇進行補充】

            網絡流建模主要分為兩類:直接用最大流建模、用最大流—最小割定理轉化為最小割來建模。這里主要總結的是前一種。

            (1)增廣路思想:
            應用范圍較小,但是確實有一些模型用增廣路思想很容易解釋,用流量平衡思想卻很難解釋(比如下面舉的例子)。
            增廣路思想可以概括為:原題的方案的得出可以很明顯地分為一些階段,每一階段都會對一些變量(這些變量可能是實的也可能是虛設的)產生同樣的效果值累加,而這些變量恰好有各自的限制,且互不關聯。這剛好相當于網絡中的一條從源點到匯點的一條增廣路,對路上所有邊的流量都會增加,且流量有各自限制(容量),且互不關聯。并且,該模型滿足下面(3)中的兩條原則(可行性原則和最優性原則)。在比較多的時候,用增廣路思想能夠解釋的模型往往是一個很明顯的“物質路徑”模型,某一種物質(可以是實的也可以是虛的)從源點往匯點“走”,邊上的流量代表物質經過的量。
            例1:[NOIP2011]觀光公交
            首先,由于來出發地的時間已知且一定,所以“旅行時間總和最小”其實就是所有人下車的時間總和盡可能小,因此,先求出在不用任何加速器(初始)情況下,到達每一站的時間,設為S[i],又設M[i]為在第i站上車的來的最晚的人來的時間,則很顯然可以得到初始的遞推式:S[i]=max{S[i-1], M[i-1]}+D[i-1](初始的D值),邊界S[0]=0。
            下面來看一下D[i]的減少是如何影響S值的。看下面這個例子:
            N=5
            i                  :  0   1   2   3   4
            D[i](初始):  3   4   3   2   \
            M[i]              : 1   2   6  14   \
            S[i](初始):  0  4   8  11  16
            現在將D[0]的值減小1之后:
            i    :  0   1   2   3   4
            D[i]:  2   4   3   2   \
            M[i]: 1   2   6  14   \
            S[i]:  0  3   7  10  16
            可以發現,D[0]值減小1之后,S[1..3]的值都減小了1,而S[4]的值不變。這是因為在D[0]減小1之前,對于1<=i<3均有S[i]>M[i],D[0]若減小1,顯然S[1]會減小1,而由于S[1]>M[1],S[1]=max{S[1], M[1]},所以S[1]的值減小1會使得max{S[1], M[1]}減小1,從而S[2]的值減小1,然后由于初始的S[2]>M[2],同樣會使得S[3]減小1,而初始的S[3]<=M[3],故S[3]減小1不會使得max{S[3], M[3]}發生變化,所以S[4]的值不會受到影響。
            所以,可以得到:D[i]減小1,會使得S[i+1..j+1]均減小1,其中j是使任意i+1<=k<=j0均滿足S[k](減小前)>M[k]的最大的j0值。
            從這個當中可以發現,對于原題的每一個可行方案,必然都是分為若干個階段,其中每一階段是將某個D[i]值減小1(當然,要滿足D[i]在減小前>0),每一階段進行后都會將從S[i+1]開始的連續的一段S值都減小1,恰好可以抽象成一條連續的路徑,又因為當S[i]減小到<=M[i]的時候就必須停止了(準確來說是不能再往后延伸了),所以每個S[i]的能夠繼續延伸的減小的量都是有限的,為初始的S[i]-M[i](如果這個值<0,則取0),剛好是一個上限。這很明顯是增廣路思想。
            所以,經過整理,可以建立一個網絡流模型:
            <1>設立兩個源點s和s'(其中s是真正的源點)及匯點t,連邊<s, s'>,容量為K,費用為0,表示最多只能有K個階段;
            <2>將每一站i拆成兩個點i'和i'',連邊<i', i''>,容量為max(S[i]-M[i], 0),費用為0,表示該點最多只能接受max(S[i]-M[i], 0)次加速器作用;
            <3>對于所有的i滿足1<=i<N,連邊<(i-1)'', i'>,容量為INF,費用為第i站下車的人數(這是因為即使S[i]<=M[i],加速器對于本站仍然有效,只是不能繼續延伸,所以表示加速器起的效果的邊應該在本站的限制之前);
            <4>對于所有的i滿足0<=i<N-1,連邊<s', i''>,容量為初始D[i],費用為0,表示使用加速器的地方,從下一站開始對S[i]起效果;
            <5>對于所有的i滿足1<=i<N,連邊<i', t>,容量為INF,費用為0,表示加速器作用的結束。
            (其實,0'和(N-1)''這兩個點是木有任何意義的,可以從圖中刪掉)
            這樣,每一階段加速器的作用都可以表示為一條從s到t的增廣路,該網絡流模型中的各種限制也反應了題目中的限制。對該網絡求最大費用最大流,得到的總的最大費用從初始的總旅行時間中減去(注意總旅行時間是long long的),即為答案。可以證明,這個模型符合“兩條原則”,所以是正確的。

            (2)流量平衡思想:
            這個思想的應用非常廣,可以解釋絕大多數網絡流模型。
            所謂流量平衡,就是指在一個可行流里,除了源點和匯點外,其余每個點的入邊流量總和都等于出邊流量總和。可以證明,一個流是可行流當且僅當其:(1)每條邊的流量都不超過容量限制;(2)符合流量平衡。
            流量平衡思想的主要用處是:可以把圖中的每條邊的流量(當然必須是非負的)都想像為一個變量的值,對于每個點,滿足流量平衡,也就是一些變量的和值滿足某種等量關系,如果這些等量關系剛好能夠反映題目中的所有信息,邊的容量限制也反映題目中的條件,且這個模型符合“兩條原則”,則該模型就是正確的了。在建模的時候,應先單獨考慮各個點,找到它們的所有入邊和出邊代表的變量是什么,然后再將這些邊合并,構成圖。
            在用流量平衡建模時有一些技巧:
            <1>要注意每條邊都同時作為一個點的出邊和一個點的入邊,因此,每個變量必然同時關聯兩個等量關系,且分別出現在這兩個等量關系的等號的左邊和右邊(或者是以一對相反數形式出現);
            <2>如果題目中給出的變量和值關系不是等量關系,而是不等關系,那么可以將剩余的流量通過從源點或往匯點連邊的辦法,使其平衡。比如,若題目中有y1+y2>=x1+x2>=y1+y2-5這樣的關系,則可以這樣做:設置一個點,將y1、y2代表的邊作為該點的入邊,將x1、x2代表的邊作為該點的出邊,然后從該點往匯點連一條容量為5的邊;
            <3>如果點內部有限制(比如某個點自身的權值不能超過X等等),那么該點內部也“暗含”一個變量,此時就需要拆點(不一定拆成兩個點,可能拆成更多的點),然后在拆出的點當中再連邊,附加一些限制,然后再考慮流量平衡;
            <4>如果一條邊有上下界,且上下界相等(也就是該邊的流量已經定死了),則可以改裝成費用流,將這條邊的費用設為一個絕對值很大的負數,這樣就肯定能保證該邊滿流了。
            例2:餐巾計劃問題(經典問題)
            這個的模型用增廣路思想根本就不能解釋。其實,可以用增廣路思想建立一個模型,但是是錯誤的,可以用下面的“兩條原則”檢查出來。
            <1>對于每天,要處理的餐巾總數=當天買的餐巾總數+當天洗好的餐巾總數+上一天保留下來的未處理的餐巾總數,這三個當作入邊;
            <2>對于每天,要處理的餐巾總數=送快洗部的餐巾總數+送慢洗部的餐巾總數+保存起來留到下一天處理的餐巾總數,這三個都當作出邊;
            <3>每天的內部有限制:要用的餐巾總數>=當天的需求量,其實,總可以構造出要用的餐巾總數=當天的需求量的最優方案,所以這些限制其實是上下界相等的。
            而<1>和<2>剛好描述了每天這個整體的流量平衡,<3>是一個內部限制,用拆點解決。仔細觀察所有的邊可以發現,“當天洗好的餐巾總數”與“送快洗部的餐巾總數”和“送慢洗部的餐巾總數”可以合并,“上一天保留下來的未處理的餐巾總數”與“保存起來留到下一天處理的餐巾總數”也可以合并。
            這樣,可以構造出兩種模型:
            1):第i天拆成兩個點i'和i'',連邊<i', i''>,容量為第i天需求量,費用為0;對于任意0<=i<N-1,連邊<i'', (i+1)''>,容量INF,費用0;對于任意0<=i<N,連邊<S, i'>,容量INF,費用p,連邊<i'', T>,容量INF,費用0;對于任意0<=i<N-m,連邊<i'', (i+m)'>,容量INF,費用f;對于任意0<=i<N-n,連邊<i'', (i+n)'>,容量INF,費用s;求最小費用最大流,最小的總費用就是結果;
            2):第i天拆成兩個點i'和i'',連邊<S, i''>和<i', T>,容量均為第i天需求量,費用均為0;對于任意0<=i<N-1,連邊<i'', (i+1)''>,容量INF,費用0;對于任意0<=i<N,連邊<S, i'>,容量INF,費用p;對于任意0<=i<N-m,連邊<i'', (i+m)'>,容量INF,費用f;對于任意0<=i<N-n,連邊<i'', (i+n)'>,容量INF,費用s;求最小費用最大流,最小的總費用就是結果。
            以上兩種模型,看上去都符合題目中的限制,也符合流量平衡,但是,模型1)是錯誤的,模型2)是正確的,這是為什么呢?

            (3)判定網絡流模型是否正確的兩個原則:
            <1>可行性原則:原題中的每一種可行方案,在建立的網絡流模型中都對應著一個“能求出的”流(一般是滿足一定的條件的流,比如某些邊必須滿流等),注意這里的對應必須是“一一對應”,就是,既不能有可行方案丟失,也不能出現不可行方案;
            <2>最優性原則:原題中的最優方案(準確來說是最優方案的結果),在建立的網絡流模型中都對應著一個“能求出的”量(最大流量或者滿足最大流量的前提下的最小費用),也就是,最優結果必須是可以通過這個模型求出的。
            一個網絡流模型正確,當且僅當其符合以上兩條原則。
            這兩個原則可以檢查所建立的網絡流模型是否正確。比如,對于例2中的兩個模型,模型1)由于最大流對應的是“買的餐巾總數盡可能多”的方案,不是最優方案,因此原題中的最優結果無法求出,顯然不符合最優性原則,因此它是錯誤的。模型2)中,由于可行方案必然能使所有<S, i''>中的邊滿流,且能夠求出,符合可行性原則;最優方案由于<i', T>這條邊的限制,必然是最大流,且是費用最小的最大流,其最小費用為最優結果,符合最優性原則,因此它是正確的。

            posted @ 2012-05-11 21:32 Mato_No1 閱讀(3895) | 評論 (3)編輯 收藏

            【首先熱烈祝賀一下進入國家隊的神犇:
            chnlich
            sevenkplus
            zw7840
            plokzfadai
            雅禮再次屠場不解釋)

            也祝賀一下雖然未能進入國家隊,但已經足夠虐爆全場的神犇:
            WJMZBMR
            s-quark

            CTSC2012得出的最主要的幾條道理:
            (1)實力強≠比賽成績好,實力弱≠比賽成績差;
            (2)現在所有的比賽都不是比誰得分多,而是比誰丟分少;
            (3)每個人都會遇到頹廢、迷茫、進步慢的時期,關鍵是如何尋求出路,以及如何通過自己與外界共同的力量來解決;
            (4)在將某個東東講給別人之前,首先要考慮一下自己是否熟練掌握了這個東東;
            (5)在分析問題,解決問題的過程中,可以通過很多另類的途徑,找到又好想又好寫的辦法。

            部分總結:
            【一試】
            showhand:
            可以將所有的牌型(C(52, 5)=2598960種)全部存儲起來,按照題目中的規則進行排序,存儲在一個線性表里,然后,枚舉A的所有可能的牌型,從上面的線性表中找到比A大且不和A共用同一張牌的方法總數,可以使用容斥原理(方法:設F[i][t]為牌型i及比i大的牌型中,與i共用牌的屬性壓縮值為t,0<=t<=31表示5位二進制數,對應位為1表示與i共用,0表示不共用)。而對于B的某些牌一開始就被定死了的情況,用求出的F類似辦法也可搞;

            shortest:
            很好的一道提交答案題。
            先說一下各個測試點的特點:
            點1:N<=20,K=10,從1到N的最長路徑若要成為最短路徑,需要刪掉至少11條邊;
            點2~3:N、M較大,K較小(分別為20和10);
            點4:N<=20,邊可以想腫么刪就腫么刪;
            點5~7:原圖分為若干塊,每塊的點數相等且較小(分別為20、10、10),相鄰兩塊之間有唯一的一條邊相連,點5的邊可以想腫么刪就腫么刪,點6、7刪邊有限制;
            點8:是一個完整的100*100的網格,邊權均為1,從左上角走到右下角;
            點9:是一個2*1000的網格,中間隨機刪掉了約20條邊,邊權是隨機值,從左上角走到右下角;
            點10:圖中存在一條從1到N的鏈(稱為主鏈),附加了一些邊,邊可以想腫么刪就腫么刪。
            解決辦法:
            點1:搜索(當然,狀壓求出最長路+將這11條邊列出來,枚舉保留哪條邊,可以得到一個僅比最優解小1的解);
            點2、3:貪心+隨機化(每次找一條從1到N的最短路,從中隨機刪掉一條邊,這樣做K次就得到一個方案,然后多次隨機化后取最優方案即可;對于點2,隨機幾千次就能找到最優解了,對于點3,RP好的話需要隨機1000W次,RP差的話可能需要上億次,估計總共得耗掉1h以上,因此得早寫);
            點4、5:狀壓DP;
            點6、7:塊內狀壓(當然由于只有10,暴搜也可),塊之間DP(設F[i][j]為前i塊刪掉j條邊的最優解……)
            點8:直接構造……(可以構造出一個只有一個點走不到的方案,且可以證明不存在走完所有點的方案);
            點9:搜索/DP + 構造(具體的實現細節比較難搞啊囧);
            點10:這個是Hamilton路徑問題,NPC的,因此這個點根本木有辦法搞囧……(當然或許有某些經過優化的搜索能較快找到解)

            【二試】
            cheat:
            80分做法1:首先將所有的字符串拼在一起,中間依次用不同的分隔符隔開,然后對這個大串求后綴數組求出height,然后就很容易求得每個屬于待查詢串部分的位置i與模板串的最大LCP(直接正著掃一遍、反著掃一邊即可,注意邊界)長度,設為D[i],接下來就是二分L然后DP了:F[i] = min{F[i+1]+1, F[j]},其中0<=i<len,i+L<=j<=i+D[i],邊界F[len]=0,這個東東顯然是可以用線段樹優化的。總時間復雜度O(Nlog2N);
            80分做法2:可以發現,對于同一個待匹配串,隨著i的減小,(i+D[i])是不增的,因為D[i]最多比D[i+1]大1……這樣可以用單調隊列進行優化,而不需使用線段樹,總時間復雜度降為O(NlogN),但是由于后綴數組常數過大,還是只有80分囧……
            100分做法:將后綴數組改為后綴自動機(詳見WJMZBMR空間)……
            (另外講題的時候某神犇說可以把后綴數組的長度減半,從而結合單調隊列得到90分,不過本沙茶木有理解到底是腫么搞的囧……)

            rev:
            點1~2:N=1或M=1,可以暴力搞(要開-O2啊啊啊啊啊啊啊啊啊啊……否則慢死)
            點6:整個矩陣從左到右、從上到下都嚴格遞減,只要滿足坐標限制的都是逆序對,可以直接計算得到;
            點7:只有5和9,且相鄰的兩個格子分別是5和9(其實可以把5和9看成0和1,相當于黑白染色),可以通過枚舉不同情況分類討論計算得到;
            點8、9:N=M=1000,詢問的區間都是從頂到底的,可以通過預處理得到一個O(N2M)近似暴力的算法,在約5min內跑出(開-O2);
            點10:N=M=80,隨機數據,可以直接暴力遞推得到;
            點3~5就比較難搞了,本沙茶至今木有搞懂囧……

            posted @ 2012-05-09 22:58 Mato_No1 閱讀(1737) | 評論 (0)編輯 收藏

            【注:本沙茶完成AHOI2007的題目用了3年多……因為6道題中,有2題是2009年AC的,1題是2010年AC的,剩下3題是2012年AC的……】

            box:
            要求x2=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的情況;

            door:
            求逆矩陣的問題。方法:設置N*N的矩陣A和B,A初始為待求逆的矩陣,B為單位矩陣,然后,不斷地對A和B同時實施相同的初等行變換,直到將A變成單位矩陣為止,此時B就是A的逆矩陣,若無論如何也不能將A變成單位矩陣,則A無逆矩陣。
            初等行變換有3種:(1)兩行互換;(2)將一行整體乘以一個非0常數;(3)將一行加到另一行上。
            具體操作:類似于高斯消元。第一步,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行就處理好了,這樣一直下去,直到所有的行都處理好為止。

            light:
            首先對這個字符串A[0..n-1]進行自身exKMP,求出nx數組,nx[i]表示A[i..n-1]與A[0..n-1]的LCP長度。
            然后,點燈器的長度為p可行的充要條件是:(1)nx[n-p]==p;(2)對于整個nx數組,取出其所有大于等于p的元素,則相鄰兩個元素的距離(下標之差)都不超過p。
            對于第(2)個條件,只要用一個線段樹維護最大距離就可以了,枚舉p的時候正、逆序均可,推薦逆序,這樣實際上等于不斷插入元素,比刪除元素要方便。

            rock:
            超級大水題。只要把矩陣中所有的0變成-1,再求最大子矩陣就行了。

            redcross:
            求01矩陣中最大的某種性質的子矩陣類的題目。最暴力的做法顯然是13個數組(原始數組+上下左右延伸0的長度+上下左右延伸1的長度+左上左下右上右下延伸的0正方形的邊長),如果把上下左右延伸0和1的長度進行合并可以減少到9個數組,但這樣對于這種如此卡常數的題目還是會TLE的。其實,可以換一種思考方式,最后只用6個數組(包括原始數組)就解決了問題……至于這個是腫么搞的,現在不能說,以后的某一天再說……
            另外這里的最優解排序……發現有驚人的地方么囧……

            maze:
            由于可以隨便走,N<=10,因此可以枚舉前5步的走法和后面5步的走法(其實全是一樣的,枚舉一次就行了,只是存儲方式不同),把能得到的所有權值和分最后到達位置(前5步)和開始位置(后5步)存在數組里,然后就是二分查找了囧……至于N<10的情況就少幾步枚舉了囧。其實還是比較難寫的,本沙茶2009年寫這題的時候寫了整整一晚上,當然這或許與本沙茶當時太太太太太……弱了有關(當然現在仍然弱)

            posted @ 2012-05-04 18:00 Mato_No1 閱讀(671) | 評論 (0)編輯 收藏

            【最近很想被各種省選題虐……于是,就開始找各種省選題……發現能虐本沙茶的實在是太多了(誰叫我是沙茶呢囧)】

            homework:
            很能令人想歪的題目……想到某種數論模型……
            正解是遞推+矩陣優化。可以這么想,本題如果暴力遞推的話,設F[i]為1到i組成的數(具體的數,不是取模以后的結果,雖然這個值是無法存儲的),則有F[i]=(F[i-1]*10T)+i,其中T是i在十進制下的位數,邊界F[0]=0。這個式子是可以矩陣優化的,矩陣為
            10T 0 0
            1 1 0
            1 1 1
            則1*3矩陣[F[i-1], i-1, 1]乘以這個矩陣之后就是[F[i], i, 1],然后對于各個T分開處理一下就行了……這里的取模完全就是個幌子……
            (另外,矩陣優化遞推是一個很重要的專題……)

            race:
            (最近剛好在某MO神犇的資料里面看到了柯西不等式……發現此題可以用這個來搞……就囧掉了)
            柯西不等式:(a12+a22+...+an2)(b12+b22+...+bn2)>=(a1b1+a2b2+...+anbn)2  【*】,
            等號成立當且僅當對于任意1<=i, j<=n, i≠j,有aibj-ajbi=0,也就是(a1, b1), (a2, b2)...(an, bn)這n個點共線。具體證明的話,把兩邊的乘法列成一個矩陣的形式,去掉主對角線(相同),把關于主對角線對稱的位置對應相減,得到類似叉積的平方和的形式即可。

            對于本題,假設不考慮耗油量為負時取0的情況,設F0=(F-Σ(b*Li*Si))/a,則問題就轉化為求一組vi使得ΣLivi=F0且Σ(Li/vi)的值最小。這樣,可以設ai=sqrt(Li/vi),bi=sqrt(Livi),代入【*】式……傻眼了囧……不僅能得到最小值,還能發現取得最小值時所有的v都相等,且可以算出來……當然如果F0<0就無解了囧……
            不過本題最囧的問題是對于耗油量為負的情況。最好的處理辦法是,如果按照【*】式得到的v值會導致某些s<0的路段耗油量為負,則對于這些路段單獨處理,使得它們的耗油量剛好為0(除非此時的速度已超過上限),并將它們刪去,然后對于剩下的路段,重新代入(*)式計算v,直到不出現耗油量為負的情況即可。當然,如果在此過程中出現F0<0,就無解了。

            brackets:
            這個應該不用再說了,直接看這里

            rectangle:
            思想比較巧妙的話說……應該枚舉線段,按照中點和線段長度進行排序(因為兩條線段若能組成矩形的兩對角線,則它們必然等長,且中點重合),然后掃一遍,順帶枚舉就是了……表面上來看時間復雜度可能到O(N3)級別,其實根本無法出卡這種方法的數據……

            canon:
            這個沒什么好說的,就是硬推公式,結果為
            (C(2n, m) - C(2n-1, m/2)) / 2n + C(2n-1, m/2) (當m % 4 == 0或3時)
            (C(2n, m) + C(2n-1, m/2)) / 2n - C(2n-1, m/2) (當m % 4 == 0或3時)
            對于當中的取模問題:加、乘直接取模;減法要在取模后判定是否小于0,若小于0再加上待取模數;除法要轉化為乘逆元(反正這里的MOD都是質數……)

            posted @ 2012-04-24 21:25 Mato_No1 閱讀(842) | 評論 (0)編輯 收藏

            相關鏈接
            今天在回顧以前的題目的時候,禿然發現COCI 2011~2012 #5的后兩題并非神犇題(至少一般人可以捉的)……是我當時想傻掉了囧……

            blokovi:
            首先很容易發現最優方案必然是從頂到底,先盡量往右邊放,放到某一個轉折點處再盡量往左邊放……
            然后就是枚舉這個轉折點,亂算一下就行了,暴力O(N2)的可以過7個點(本沙茶現場賽時就是用這個的)……
            優化:可以從上到下依次枚舉轉折點,設目前的轉折點為i,則在下一次枚舉時((i+1)為轉折點),把(i+1)往右平移2單位,然后根據那個重心計算公式可以得出,第(i+2)個及以后的必然是整體向右平移(2*m2)/(m1+m2),其中m1為前i個的質量和,m2為第(i+1)個的質量……在此基礎上維護轉折點前重心位置、轉折點的重心的橫坐標(相對于最上面的那個)以及最下面的那個的重心的橫坐標(相對于最上面的那個)就行了(注意轉折點是第一個或最后一個的特殊情況要單獨處理),時間復雜度O(N)。

            poplocavanje:
            其實這題只要用AC自動機隨便亂搞一下就行了……Trie上的每個結點維護一個KK,表示該結點所代表的字符串的后綴的最大匹配長度(當然前提條件是該結點是危險的),則:(1)若該結點本來就代表一個待匹配的子串,則KK值為子串長度;(2)若該結點是通過失敗指針上溯到一個危險結點的,則該結點的KK就是上溯到的那個危險結點的KK。然后做一次匹配,記下所有的匹配區間,再求出未被區間覆蓋的總長度(排序+掃描即可,不需任何數據結構)就行了。

            注意幾個易疵的地方:
            (1)Trie的大小要開到4M才能過(不過再大就要MLE了囧……);
            (2)在建自動機計算KK的時候,如果一個結點本來就是危險的(即上述第1種結點),此過程中又發現它是上述第2種結點,則能重新計算KK
            (3)最后求未被區間覆蓋總長度的方法:先記下所有的區間,按照先左端點遞增序后右端點遞增序排序,當中去掉被別的區間覆蓋的區間,然后先看一下排序后的第一個區間和最后一個區間,得出第一個區間之前與最后一個區間之后的未被覆蓋的部分,中間的掃描求解時,如果某區間的左端點大于(前一區間的右端點+1),則計入中間的空當……不過還有一種方法就是不去掉被別的覆蓋的區間,而是在掃描過程中維護右端點最大值maxr,然后把上面方法中的所有右端點改為maxr即可。

            代碼:
            blokovi poplocavanje

            posted @ 2012-04-18 20:26 Mato_No1 閱讀(779) | 評論 (0)編輯 收藏

            【很難過吧……考得完爆了……
            ……其實也沒什么可以說的……都是蒟蒻的借口罷了……
            ……自己果然還只是半吊子水平呢……】


            (結果:Rank36……我是“真”沙茶!!!!!!!!!!!!!!!Orz Mike_Qiao神犇虐人)


            題解以后再發。


            posted @ 2012-04-15 01:19 Mato_No1 閱讀(957) | 評論 (3)編輯 收藏

            歷經千辛萬苦總算搞定了COCI 2011 OPEN的所有題……真WS啊囧……
            (不過除了sort的滿分算法稍微看了一下題解之外,其它的題目都是自己想出來的……這說明本沙茶想算法的能力并不差……只是所用的時間有點……)

            sort:很容易想到該置換的循環分解,然后對每個長度大于1的循環進行一次操作就成了,總操作次數是長度大于1的循環個數。但是,這并不是最優解(在官方數據中,這個算法能過4個點,加上剩下6個點的一半分總共是70分,所以現場結果中多數人都是70分……)。最優解是先通過一次操作把各個長度大于1的循環攪亂,使得整個置換只有一個循環,然后再來一次操作就行了,也就是任何置換都最多只要兩次操作就行……至于攪亂的方法,只要在原來的各個循環(當然是長度大于1的)中各抽出一個元素,再對這些抽出的元素執行一次題目中的操作即可(證明是很容易的)。不過要注意只需0次或1次操作的情況:當原置換長度大于1的循環總數為0或1時;
            至于具體的操作構造方法隨便亂搞一下就行了囧……

            telka:應該算是最水的一題……樹狀數組的裸模型“改段求段”(具體見這里),唯一值得注意的就是在改段求段模型中的一個注意點:當l=1的時候,不能執行opr(l-1, c),因為凡是下標遞增的數組都不能以0作為初始下標;

            rijeka:這題比較坑人啊囧……如果任意時刻最多只能載一個人,可以把每個人的要求(也就是每條有向線段)都拆成若干個元線段,然后統計正反元線段的個數,亂搞一下就成了……不過這題目里面是可以載任意多的人……那么最優策略是:先把所有反方向線段覆蓋的總區間求出來,比如有4->2、6->3、9->8三條反方向線段,則覆蓋的區間就是[2, 6]和[8, 9],然后在送人的時候,每送到一個區間的右端就回頭去把這個區間內的要走反方向的人全送到,然后再回頭往正方向開(比如上例中先從0到6,回到2,再從2到9,回到8,再回頭往前一直開到終點),這樣開到終點時,所有的人就都送到了,因此,總時間就是(M+反方向線段覆蓋的總長度),用線段樹來搞。此外,由于M太大,需要離散化。

            后面兩題就是猥瑣題了。

            kamion:很明顯是個遞推……但是按照常規方法根本無法劃分狀態。不過,要發現本題和括號序列類的動態規劃神似,因此就可以用括號序列的來搞。關鍵是,對于那些第3種邊(既不含左括號也不含右括號的)比較難搞,另外本題還允許到終點的時候有左括號(就是大寫字母)剩余,這就明顯加大了難度。
            狀態設計應是這樣的:F[i][j][k][s0][s1],表示從i到j走正好k步,且滿足單多段限制(s0)和多余左括號限制(s1)的合法路徑總數,s0、s1為bool,s0表示是單段還是多段的規則括號序列,0:單段,1:單段或多段;s1表示是否可以有多余左括號,0:不能有;1:可以有(當然也可以木有,也就是s0和s1都是0包含在1之中的)。
            遞推式:
            F[i][j][k][0][0]=ΣF[t1][t2][k-2][1][0](其中<i, t1>邊有一左括號,<t2, j>邊有一右括號,且兩括號匹配);
            F[i][j][k][1][0]=ΣF[t1][t2][k-2][1][0] + Σ(F[i][t][k'][0][0] * F[t][j][k-k'][0][1]) (注意0<k'<k,其它的類似);
            F[i][j][k][0][1]=ΣF[t1][t2][k-2][1][0] + ΣF[i][t][k-1][0][1](其中<i, t>邊有一左括號,其它的類似);
            F[i][j][k][1][1]=
            ΣF[t1][t2][k-2][1][0] + Σ(F[i][t][k'][0][0] * F[t][j][k-k'][1][1]) + ΣF[i][t][k-1][1][1](與上面的限制類似);
            邊界:F[i][i][0][0..1][0..1] = 1,當<i, j>邊為第3種邊(不含括號)時,F[i][j][1][0..1][0..1] = 1,其余的均為0。
            這幾個式子還是比較好理解的,要注意的是在計算F[i][j][k][1][1]時,是F[i][t][k'][0][0]而不是F[i][t][k'][0][1],這是為了防止重復計數(否則,對于序列AB,到底是A是附加上的,B是原來就有的,還是都是附加上的?顯然被計2次了);
            時間復雜度O(N3K2),官方題解里面說這個就能AC了,可是本沙茶實測的結果卻有5個TLE,最慢的點達14+s,可見其常數之大,本沙茶暫未想出神馬好的優化方法,神犇們可以提供一些啊囧(最好能降一維);

            lovci:(這題本沙茶調了3個晚上啊啊……)
            本沙茶所見過的最猥瑣的暴搜題目了。由于當M>0時,初始位置就會被計入(本題的真正意思是每個格子只被計入一次,而不是每次移動中初始位置控制不到的地方就計入一次),因此不用考慮初始位置。仔細分析題目發現,可以對矩陣進行黑白染色,這樣兩個初始位置一個只能控制黑格,一個只能控制白格,這樣就把兩個分開了。然后,把所有的黑格和白格給旋轉45度,變成一個十字型,剩下的任務就是枚舉哪些列被占用,然后再選出哪些行能被占用就行了。
            問題是,有的列不能隨便選,有的行也不能隨便選,這下就囧了,需要很多東東來控制,當然,本題需要注意的點太多了,實在列舉不完,見代碼吧囧。

            代碼:
            sort telka rijeka kamion lovci

            posted @ 2012-04-01 20:42 Mato_No1 閱讀(748) | 評論 (0)編輯 收藏

            僅列出標題
            共12頁: 1 2 3 4 5 6 7 8 9 Last 
            久久www免费人成精品香蕉| 久久er99热精品一区二区| 久久成人国产精品| 伊人久久国产免费观看视频 | 欧美性大战久久久久久| 国产婷婷成人久久Av免费高清| 久久久久高潮综合影院| 中文字幕精品久久久久人妻| 热综合一本伊人久久精品 | 国产精品日韩深夜福利久久| 99国产欧美精品久久久蜜芽| 国内精品久久久人妻中文字幕| 久久精品国产久精国产思思 | 久久久久久午夜精品| 久久综合狠狠综合久久97色| 亚洲成av人片不卡无码久久| 久久综合成人网| 国产欧美久久久精品影院| 一本一本久久aa综合精品| 性色欲网站人妻丰满中文久久不卡| 亚洲中文字幕无码久久精品1| 99久久精品费精品国产一区二区| 国产一区二区三区久久| 久久久WWW免费人成精品| 久久人人爽人人爽人人片av麻烦| 人妻久久久一区二区三区| 久久中文字幕一区二区| 久久无码人妻精品一区二区三区| 久久久久久久女国产乱让韩| 精品免费tv久久久久久久| 久久久久这里只有精品| 日韩人妻无码一区二区三区久久| 岛国搬运www久久| 亚洲人AV永久一区二区三区久久| 精品乱码久久久久久久| 久久久久99精品成人片三人毛片 | 蜜臀久久99精品久久久久久小说| 久久青青草原精品影院| 亚洲国产日韩综合久久精品| 国产精品99久久不卡| 亚洲国产精品无码久久SM|