• <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>

            Climber.pI的OI之路

            Through the darkest dark,may we see the light.

            #

            Problem List(2.6 ~ 3.19)

            2.6

            poj 3660[Floyd]
            [題意]
            給定n個點, m條有向邊, 判斷有多少個點的位置唯一確定.
            [做法]
            從對每個節點的度分析入手. 利用Floyd傳遞閉包, O(N^3)足矣, 統計所有 入度+出度 = 頂點數-1 的點的個數, 顯然如果一個點x, 與其他n-1個點的關系確定, 那么這個點的位置可以確定.
            *一開始從度的分析入手(這是對的, 但是要傳遞閉包), 之后認為是拓撲排序, 在這之后就沒有思路了. 但事實上這時候不應該看題解, 至少應該進行30min的思考.
            *傳遞閉包有O(N^2)的做法, 參見去年的shock, 大意是每增加一條邊(x, y), 對于任意(a, x), 使得(a, y)連通; 對于y的處理同理.

            *每周的訓練時間大致是周一下午, 周三一節課.

            2.8

            poj 3661[DP]
            比較奇怪的DP, 去年查閱各種題解后A了, 今年還是不會做 = =|||
            [狀態]f[i][j]表示第i秒后, 體力值為j時的可以到達的最大距離.
            很自然的得到了第一個方程
            f[i][j] = max{f[i-1][j-1] + d[i], f[i+j][0]}
            很明顯兩個狀態要求的規劃方向矛盾.
            于是自然的YY了一個錯誤的方程
            f[i][j] = max{f[i+1][j+1] + d[i], f[i+j][0]}
            但事實上應該這樣考慮
            f[i][j] = f[i-1][j-1] + d[i]
            f[i][0] = max{f[i-1][0], f[i-j][j]} (i-j >= j && j <= m) => (j <= min(i/2, m))
            即對不同的規劃方向分別處理.
            *本題的關鍵即對不同規劃方向的處理, 其實想一想不見得想不出來

            2.13

            poj 3663[數學/二分/枚舉], 1h
            很簡單的題目, 但是由于各種細節考慮不周, 連對拍在內寫了1h = =|||
            [1] 顯然可以O(N^2)枚舉, 然后隨便排序一下, 就可以0.6s通過了.
            [2] 我想到的一種很疼的O(N)做法
              (1) Cnt[n]表示1..n的值的個數, 可以利用前綴和得到
              (2) 對于每個L_i, 累加Cnt[S - L_i] - (2*L <= S), 需要討論S - L_i >= Max{L_i} 和 S - L_I <= 0的情況
              (3) 顯然每對數都被計算兩次, 輸出ans/2即可
            [3] 官方題解的O(NlogN)做法
              (1) 排序
              (2) 對于每個Lower, 計算滿足題目的最小Higher, 累加Higher - Lower即為答案

            poj 3664[排序]
            利用qsort對A[]間接排序, 然后利用O(K)的時間循環檢查最大值即可, 復雜度O(NlogN)

            poj 3665[模擬]
            很像是數據結構題的小范圍寫法 = =|||
            按照題目模擬即可.

            2.20

            poj 3662[最短路+二分]
            [題意]
            給定N個點, P條雙向帶權邊, 其中K條邊的權可以為0, 求最大邊權的最小值.
            [做法]
            根據描述很容易想到二分, 注意到題目對前K條邊的具體情況沒有要求. 用f(M)表示最大邊權為M時是否可行, 把邊權大于M的邊賦值為1, 小于M的邊賦值為0, 求最短路即可.
            *這里并不能使用BFS求最短路, BFS僅在無全圖中可求最短路.
            *注意二分的寫法, 可以打出f(M)的值觀察條件
            *注意無解和0的區別

            3.5
            MAR12 Silver[未實現]
            P1
            [Brief]
            在1000*1000棋盤上從(x, y)到(1, 1), 給定N個定點, 最少通過N個定點中的幾個點.
            [Solution]dij+heap, O(ElogV)
            對每個點u, 如果其周圍有定點v則 w(u, v) = 1, 否則w(u, v) = 0. 易知|V| <= 4*1000^2, 直接求(x, y) 到 (1, 1) 的單源最短路即可.
            P2
            不會做...
            P3
            同上 > <

            3.12
            MAR12 Bronze[我墮落了...]
            P1: std將17拆分為16+1, 從而避免了進制轉換.
            P2
            [Brief]
            從(0, 0)開始, 僅在N個頂點可以轉彎(90或180), 求有多少序列可以僅經過一次所有點, 并回到原點.
            [Solution]
            O(N!)生成序列, 直接利用坐標判斷是否合法即可.
            P3
            [Brief]
            給出一個序列(L <= 10^5), 每個字符可能是三個操作符F/L/R其中之一, FJ打錯了一個字符, 試統計可能到達多少種不同的終點.
            [Solution]
            (1) 掃描序列, 記錄每個點的位置, 可以得到任意兩點之間的向量. 
            (2) 枚舉每個位置可能的錯誤字符, location(n-1) + (n -> dimension)即為答案. 
            (3) 記錄每個可行終點, 利用排序去重.
            總復雜度O(N+N+NlogN) = O(NlogN).

            3.15
            MAR12 Silver
            flowerpot[Heap/二分+RMQ]
            [Brief]
            給定N個坐標, 滿足|y_j - y_i| >= D, 求|x_i - x_j|的最小值, 若不存在最小值則輸出-1.
            *題目真心看不懂, 看了樣例才懂了.
            [Solution]
            [1] O(N^2)暴力枚舉每個坐標
            [2] O(NlogN)
              (1) 對x升序排序
              (2) 求出y的區間最大/小值
              (3) 二分|x_i - x_j|, 這里需要記錄對于每個x_i, x_i+D的位置(可能不存在)
            -> 這個思路非常麻煩, 不可行
            [3] O(NlogN), 利用Heap
            和我最初的想法一致.
              (1) 對x升序排序
              (2) 對于每個x_i, 找到最近的x_j, 滿足|y_i - y_j| >= D
            事實上(2)可以進一步強化為|max{y} - min{y}| >= D, 也即若區間[i, j]滿足題意, 但|y_i - y_j|不滿足題意, 則其中必有子區間滿足|y_i - y_j| >= D
            [譯自官方題解]
            我們首先對所有點的x進行排序, 然后利用一對豎直的掃描線, 從左至右遍歷整個平面. 一對掃描線之間的點的y值, 利用一個能夠快速查找最大/最小值的數據結構存儲, 例如STL multiset(如我們在下文所使用), 或者一對堆. 每當最大和最小的y的差至少為D時, 我們檢查此時是否得到目前位置的最優結果, 之后將左掃描線向前移動. 否則, 我們將右掃描線向前移動. 算法總的運行時間為O(NlogN).
            *對(2)進行強化后, 可以避免大量冗余操作
            *強化后, (2)可以直接使用Sparse Table在O(1)得到最值. 效率應略高于官方題解.

            3.19
            [利用qsort對結構體排序]
            int cmp(const void *a, const void *b){
                point *A = (point*)a, *B = (point*)b;
                return (A->x > B->x) ? 1 : -1;
            }
            *A是一個指針, *A = (point*)a表示把無類型指針a轉換為point型的指針
            int cmp(const void *a, const void *b){
                int i = *(int*)a, j = *(int*)b;
            return (i > j) ? 1 : -1;
            }
            i = *(int*)a表示先把無類型指針a轉換為int型的指針, 然后利用*得到指針所對應的值

            flowerpot[區間掃描+RMQ(Sparse Table)], 40min
            (1) 對x升序排序(由于之后需要得到區間最值, 直接對結構體排序, 而非間接排序)
            (2) sprase_table
            *f[i][j] = max{f[i][j-1], f[i + 2^(j-1)][j-1]}, 初始化f[i][0] = P[i].y
            (3) 區間掃描, 初始區間[i = 1, j = 1]
              i) 若區間[i, j]滿足題意, 嘗試更新答案, ++i
              ii) 若區間[i, j]不滿足題意, ++j
              *對于操作i, 此時區間合法, 為了得到最短區間, 左指針右移.
              
            landscape[DP, 編輯距離], 1h
            [Brief]
            給定一個長度為N(N<=100)的序列, 序列中的每個元素權重為a_i(Σa_i <= 1000), 對A_i加1需要付出代價X, 對a_i減1需要付出代價Y, 把1個單位從a_i移動到a_j需要代價(j-i)*Z, 求把序列a_i變換為序列b_i(Σb_i<=1000)的最小代價.
            [Solution]
            [1] 最初由N的范圍猜測是DP, 用f[i][j]表示前i-1個元素已符合題意時, 第i個元素權重為j時的代價. 遂發現此時存在后效性, 無果而終. 進而猜測可能是網絡流模型, 參看題解.
            *和GDKOI 2012 Day1一樣, 最初的想法是正確的, 略深入的想法是錯誤的, 但此時切換角度思考就能得到正確結果.
            [2] 換一種角度, 我們考慮每個代價的位置序列A_i, 變換為B_i. 序列A_i和B_i單調不降. 考慮到題目中的三種操作, 套用"編輯距離"模型.
            [狀態] f[i][j]表示A_1..i和B_1..j符合題意時的最小代價
            [方程] f[i][j] = min{f[i-1][j] + Y, f[i][j-1] + X, f[i-1][j-1] + Z*|A[i] - B[j]|}
            [初值] f[i][0] = Y*i, f[0][j]= X*j
            *對于確定大致方向的題目, 可以分別考慮題目中涉及的幾個量, 進而得到解法.

            posted @ 2012-03-19 18:49 Climber.pI 閱讀(162) | 評論 (0)編輯 收藏

            Problem List(1.25 ~ 2.1)

            //GDKOI 2012之前涉及的題目, 由此可見寒假真的什么都沒做

            1.25

            air[二分圖最大匹配 -> 最大流], 1h
            [建圖]
            (1) 在飛行員u和外籍飛行員v間增加有向邊(u,v), 同時增加源S到u的邊(S,u), 以及v到匯T的邊(v,T).
            (2) 考慮到n<=100, 利用鄰接矩陣存儲, 上文增加邊容量為1, 其余為0, S到T的最大流即為答案.
            (3) 直接利用map記錄u和v的對應關系
            *數據的方案似乎不是最小字典序, 此外題目中未涉及方案的順序問題, 暫不考慮.

            path[最小路徑覆蓋 -> 二分圖最大匹配 -> 最大流], 1h
            注意到在路徑覆蓋中, 每個點只能被覆蓋一次. 
            [建圖]
            將每個點拆分, 然后源S和匯T分別連邊, 點間按照題目要求連邊, 求最大流f即可.
            顯然如果要增加一個路徑覆蓋, 必須存在某點沒有前驅(或后繼), n-f即為所求.
            [輸出方案]
            利用flow數組從1開始遍歷, 用vis標記已訪問點即可.

            某題 by ftiasch
            Given two sorted arrays A, B of size m and n respectively. Find the k-th smallest element in the union of A and B. You can assume that there are no duplicate elements.
            http://www.leetcode.com/2011/01/find-k-th-smallest-element-in-union-of.html
            [O(log(n+m))做法]
            你假設求第k大嘛, 肯定是這邊來前i個, 那邊來前j個. 然后二分i, 就有j了. 然后check一下合法否.

            1.27

            poj 2976[分數規劃 -> 參數搜索]
            [定義]一般地, 求max{a(x)/b(x)}, a(x) b(x)是實值函數, 且b(x)>0.
            特別地, 如果max{a(x)/b(x)} ∈ (0,1), 稱為0/1分數規劃
            [解法]
            不妨設lambda即為所求.
            顯然滿足 a(x)/b(x) >= lambda (注意大于等于號)
            整理可得 a(x) - b(x)*lambda >= 0
            顯然存在任意x值滿足lambda即可, 比如在這種情況下可以求函數最大值, 若最大值不滿足, 那么顯然這個lambda不會得到滿足.
            設g(lambda) = max{a(x) - lambda*b(x)}
            分析可知:
            g(λ) > 0 <=> λ' < λ
            g(λ) = 0 <=> λ' = λ
            g(λ) < 0 <=> λ' > λ
            轉換為0/1分數規劃后, lambda ∈ (0, 1), 可以二分lambda, 注意a(x)和b(x)的求法因題目而異.
            *比如最優比率生成樹問題
            *可以利用qsort直接對double排序, 寫法和int一致, 需要注意排序時return x > 0 ? 1 : -1;不要返回0
            *對于浮點誤差, EPS = 1e-8, 越小越好(時間代價?)

            1.31

            GDKOI 2010分析[未驗證]
            30 + 20 + 12 + 12 = 74
            30 + 40 + 20 + 12 = 102
            考慮到實際情況, 以及對拍時間, 似乎150+并非不可能.
            Day1
            [1]load
            AC, 改變松弛條件的最短路, 可以使用Floyd
            [2]goodjob
            30%, 裸DFS
            AC, 狀壓DP
            [3]pizza
            30%-50% 亂搞, 利用最大m段和或者分數規劃
            AC 利用周期數列的性質?不明.
            [4]plan
            30% 暴搜?
            AC 費用流
            Day2
            [1]collection
            數學題, 通過簡單的變形得到函數, 可以利用三分法或者Cauthy不等式求解
            [2]cook
            10% 暴搜, 生成全排列
            AC 4維DP
            [3]table
            50% BFS
            AC 雙向BFS
            [4]push
            30% 模擬
            AC 利用掃描線思想, 對坐標排序[具體不明...]

            GDKOI 2011分析[未驗證]
            30 + 20 + 8 + 12 = 70
            24 + 20 + 12 + 12 = 68
            考慮到考場上可能的問題, 大概能保證100.
            Day1
            [1]sewer
            DFS/BFS/...隨便模擬
            *小數據驗證
            [2]park
            50% 對于每個長方形, 枚舉每棵樹是否在其上, O(NM)
            AC 通過某種操作把驗證某個樹在某個矩形上, 由O(N)降至O(logN), 比如平衡樹
            *小數據驗證, 如果構造AC算法必須對拍
            [3]mission
            20% 模擬
            AC T_T我不會
            [4]move
            30% BFS
            AC A*/狀壓DP
            *小數據驗證
            Day2
            [1]weight
            30% DFS, O(3^N)
            AC 分成兩堆, 分別進行DFS, 然后對于每個砝碼組合m, 在另外一堆里找n, 使得m+n滿足題意即可.
            *兩種思路對拍
            [2]ponytail
            50% 簡單分析之后利用整除性和打表暴力
            AC 進一步的分析, 利用歐拉函數求解
            根據題意
            s >= x + y ...(1)
            1/x + 1/y = 1/z ...(2)
            由(2)可得, x+y | xy ...(*)
            設(x, y) = d
            可得x = d * x1, y = d * y1
            代入(*)可得 x1+y1 | dx1y1
            易證x, y分別和x+y互質
            令d = t(x1 + y1), 代入即得
            s = x + y = t(x1 + y1)^2
            令n = x1 + y1, 顯然滿足題意的n的個數為歐拉函數φ(n), 滿足題意的t的個數為[S/n]
            綜上可得, Σφ(n)*[S/n]即為所求.
            [3]bright
            30% 最大流
            AC T_T我不會
            [4]eight
            30% DFS
            AC 狀壓DP
            => 導出結論, 主要復習暴搜, 其次復習基本算法, 如圖論若干, ST等.

            2.1
            rqnoj 70 八數碼難題[BFS+hash], 2h
            BFS實現, 利用hash判重(簡單的取余法)
            *移動步驟考慮不周, 可以直接利用數組存儲, 四個方向分別為±1或3; 需要注意±1, 即左右移動后, 0必須在同一行
            *hash寫錯

            雙向廣搜, 擴展完一邊的該層節點, 再擴展另一邊的一層節點, 直到兩邊狀態相遇.
            http://longxiaozhi.is-programmer.com/posts/24858.html
            實現無能, 遂放棄.

            posted @ 2012-03-19 18:48 Climber.pI 閱讀(114) | 評論 (0)編輯 收藏

            GDKOI 2012及其他

            一周之前的此時, 我應該在廣州的地鐵上, 帶著悵然若失.
            41 + 58 = 99, 二等分數線102, 其實也沒什么可說的, 寒假沒干正事, 結局如此確是正常.
            本來打算寫點東西, 現在看最近幾天完成這個難度有點大, 這個月抽時間寫吧.

            "心中隨生一種風云際會但終將風流云散的感覺"

            Day2結束的時候, 看著wx神牛的成績單, 無比詫異, 雖然帶著一大堆行李, 卻也去復評了一吧. 反正沒機會再以選手身份來了, 倒不如把流程都體驗一遍.
            這幾天漸漸的開始籌劃CMOp了, 其實也就半年而已, 我也不知道自己能走多遠. 漸漸的回憶起了以前不長的MO生涯, 刪了一下午文件, 刪著刪著又悵然若失了. 現在聽輕音樂又和NOIp前一樣, 又開始覺得一股絕望溢出胸口.

            而我, 卻不知道憂傷從何而來.

            posted @ 2012-02-11 20:25 Climber.pI 閱讀(274) | 評論 (0)編輯 收藏

            Problem List(11.19 ~ 12.26)


            11.19

            poj 1258[Kruskal]
            和training的那題一樣, 注意有多組數據
            *數組開錯, 沒有區分MAXn/MAXedge

            11.21

            poj 1944[DP], unAC
            沒看出來是DP.
            網上有兩種做法:
             (1) 三維DP
             (2) 兩個二維DP

            快速讀入 by gXX
            int getInt() {
             char ch = getchar();
             while (ch < '0' || ch > '9') ch = getchar();
             int ret = 0;
             while ('0' <= ch && ch <= '9') {
              ret = ret * 10 + ch - '0';
              ch = getchar();
             }
             return ret;
            }
            qc #20:
             getInt(), 0.06s
             fscanf(), 0.2s
             fstream, 0.35s
             
            11.28

            馬走日問題[回溯], 1h
            *lrp問了, 昨晚隨便敲了一下, 發現想得亂七八糟, 果然要想清楚問題再敲.
            求(1, 1)到(m, n)的路徑數, 注意回溯邊界即可.

            NOIp2011P, 統計單詞數[字符串], 1h
            讀入文章中的每個單詞, 轉換大小寫后, 和已知目標單詞比較. 記錄相同單詞數, 及每個單詞的首字母在文章中位置即可.
            *trick:
            (1)文章中單詞間可能存在多個空格, 因而需要讀入每個字符
            -> 需要注意的是, 需要刪除pdf樣例中多余的空格
            (2) 文章中的單詞長度可能遠大于目標單詞長度
            *很像叉姐第一次模擬題的第一題

            NOIp2011P, 瑞士輪[雙關鍵字排序], 60, 40min
            *樣例說明很詳細
            需要注意雙關鍵字排序和間接排序的區別:
            (score[i] < score[j] || (score[i] == score[j] && i > j))
            這里直接比較i和j, 而非id[i]和id[j].
            *我覺得我這么廢都能一等就是一個奇跡.. >_<

            11.30

            NOIp2011T, 選擇客棧[數學], 2h
            (1) 注意到各顏色間相互獨立, 不妨單獨處理
            (2) 題目要求找到區間中存在任意滿足條件點的區間個數, 即所有子區間的個數減去連續不滿足條件的區間個數
            *邊界各種掛, 調試無能

            12.5

            NOIp2011P, 瑞士輪, 1h
            *非常心不在焉
            *注意靜態查錯 -> 如果出現循環, 大部分正確, 最后出現錯誤的情況, 極有可能是打錯變量.
            *注意數組的實際意義, 如存儲標號還是值
            (1) 以force[]為第一關鍵字降序, id[]為第二關鍵字升序排序
            (2) 注意到過程中只有N個元素+1, 其余N個元素不變, 且對于變化或者不變的元素, score[]單調遞減
            故而對于每組選手(i, j), 利用隊列A[]存儲勝利選手, 隊列B[]存儲失敗選手
            (3) 按照雙關鍵字合并隊列A[]和B[]
            (4) 將(2)(3)進行R輪, 輸出id[Q]即可

            NOIp2011T, 選擇客棧, 1h
            (1) 利用鄰接表(數組實現), 按顏色存儲客棧; 利用前綴和sum[i]表示1..i中cost_i <= p的客棧個數
            (2) 對于每種顏色的每個區間預處理part[], 表示該區間是否符合條件
            (3) 利用補集思想, 計算連續的不符合條件區間, C(2,N) - ∑C(2,N_i);
            初始化pos = 1; 對于當前指針k, 若part[k] == 1, 則ans -= C(2, k-pos+1), pos = k+1; //pos記錄當前第一個不符合條件區間的標號
            *邊界比較麻煩, 實現之前應該計算好
            *盡可能分開不同步驟, 降低思維難度

            12.12

            NOIp 2011P, 表達式的值[表達式樹], 1.5h, 80
            *實際上50min就寫完了, 查錯查了很久
            (1) 建樹(左閉右開區間)
             1) 找到括號外第一個+或*(即結合性反方向在括號外第一個運算符, 利用p記錄是否在括號中)
             2) 若不存在+, 令posO=posA
             3) 遞歸build_tree(L, posO), build_tree(posO+1, R)
                若不存在*, 則遞歸build_tree(L+1, R-1)
             *[優化] 每次過程執行前, 脫去所有括號, 需要記錄括號位置; 如果直接判斷端點, 可能會出現(*)+(*)的情況, 導致WA
            (2) treedp(其實就是簡單統計)
             1) op[i] == '*'
              f[i][0] = (f[i.l][0] + f[i.l][1])*(f[i.r][0] + f[i.r][1]) - f[i.l,1]*f[i.r,1]
              f[i][1] = f[i.l][1] * f[i.r][1]
             2) op[i] == '+'
              f[i][0] = f[i.l][0] * f[i.r][0]
              f[i][1] = (f[i.l][0] + f[i.l][1])*(f[i.r][0] + f[i.r][1]) - f[i.l,0]*f[i.r,0]
             *如果左子樹或右子樹不存在, 則f[i.k][0] = f[i.k][0] = 1(特判, 直接賦值引起錯誤)
            *樸素的表達式樹是O(N^2)的, 常數較小, 可以利用兩個奇怪的棧做到O(N). by gXX

            12.19

            NOIp 2011T, 觀光公交, 研究題解.[*待實現]
            *真是每周一題我擦...
            (1) 初步的分析包括不使用加速器時的時間計算, 以及對加速器對時間影響的簡要分析. => 一個比較關鍵的結論是, 加速器對時間的影響一定是一個連續段
            (2) clj題解給出了一種非常高效的O(M+NlgN)做法, 實質上利用堆處理了取最大值的問題.
            (3) O(kN)的做法比較好理解, 實質是利用g(i)數組表示d[i]-1可以影響[i, g(i)]的時間值, 對于每個加速器找最大值即可. 看起來時間可能比較尷尬, 不過實測效果很好.

            12.26

            NOIp 2011T, 觀光公交[貪心+遞推], AC
            [1] 10% 做法, O(N)
            每個景點的最晚出發時間
            time[i] = max{T_j} (A_j = i)
            每個景點的到達時間
            enter[i] = max{time(i-1), enter(i-1)} + D[i-1]
            景點1..i的游客數為sum[i]
            ans = Σ(enter[B[i]] - T_i) (1 <= i <= M)

            [2] 20% 做法, O(N^2)
            僅考慮一個加速器, 嘗試將其用于任意兩個連續景點間, 記錄最小值.

            [3] 60%做法, O(kN^2)
            可用反證法證明, 當前加速器在最優位置時, 前一個加速器必然在最優位置. 符合貪心選擇性質.
            因而, 對于每個加速器, 重復20%做法即可, 非常易于編寫.

            [4] AC做法, O(kN)
            分析易知, 若對景點i到景點i+1應用一個加速器, 景點i之前的距離不受影響, 景點i之后僅當enter[i]-1 >= time[i]有影響, 因而受影響的若干個景點必為一連續線段.
            g[i]表示在景點i到景點i+1應用一個加速器, 連續段[i, g(i)]受到影響, 可得
            [方程]g[i] = g[i+1] (enter[i] > time[i])
                i+1 (enter[i] <= time[i])
            [邊界]g[N-1] = g[N]
            (1) 初始化數組
            (2) 對于D[i] > 0的段, 計算max{sum[g[i]] - sum[i]}, 應用加速器
            (3) 對于[i, min(g(i), N-2)]更新enter[]和g[]
            (4) (2)(3)重復k次
            *60分做法的只有50行, AC做法也不過70行. 60分做法只要對題意理解清楚不難實現, 10+min可以寫完. AC做法發現了連續性質, 利用遞推將尋找最優位置的耗時從O(N^2)變為O(N^2), 有一定思維難度, 但是和Day2P2的難度相差無幾.

            [5] AC做法, O(M + NlogN)
            基本同上, 無需使用g[]數組, 對于每個路徑一次應用多個加速器, 利用堆求得最大值.
            未實現, 參考clj題解.

            posted @ 2012-01-03 13:59 Climber.pI 閱讀(161) | 評論 (0)編輯 收藏

            Happy Ending

            好在一等了.
            390 = 100 + 60 + 20 + 100 + 100 + 10, 省排62, 市排2.
            Day1 180, 省排152; Day2 210, 省排24.
            主要是我AC了Day2P2, 那題全省的AC率只有10%左右.
            和那天的密碼一樣, 真是Happy Ending.
            -----------------------------------
            但是, 身邊的人的悲傷, 太多了

            posted @ 2011-11-23 20:52 Climber.pI 閱讀(178) | 評論 (0)編輯 收藏

            NOIp 2011 隨記

            去年在紀中, 我看到成績單直接傻了.
            當年會寫270, 結果DP寫掛了, 數組開小, 應該30, 結果爆零;
            第四題, 30min, floodfill沒調出來
            于是直接130, 所幸還有個三等
            -------------------------------------
            今年比去年淡定多了
            Day0果斷去逛紀中

            Day1還是很緊張, 題目很簡單, 30min想出算法, 題意抄了滿滿一頁
            被叉姐模擬賽的WA嚇怕了, 第一題就開始對拍, 寫完兩個程序外加gen, 已經過了1h了
            第二題寫了四個版本的程序O(N^2) -> O(N^3) -> O(N^2) -> O(N^2)
            一開始還看錯題了, 還好查出來了.
            擔心時間不夠, 沒敢想O(N)的AC算法, 卻用了10min敲了ST, 所幸敲對了
            第三題果斷寫30分, 結果最后還是沒調出來

            Day2開始淡定了, 題目5min看完, 第一題瞬間想到AC算法, 二三題無思路
            于是半個小時, 敲完了第一題, 看著旁邊的人手足無措, 有些洋洋自得
            接下來敲第二題的暴力敲了30min, 出去了一趟, 瞬間想到了二分+前綴和優化, 又是30+min, 敲了AC算法
            糾結了一下二分, 然后開始看第三題
            突然發現對拍器聽了, 修正了一個邊界問題, 和昨天相仿, 只剩下40+min了
            很快的YY了一個40分的DP, 卻對正確性和邊界毫無把握
            于是寫了一個10分的, 然后想20分的時候, 突然找到bug, 修正了
            交卷的時候, 瞬間想到20分寫法, 但是沒時間了

            Day2的發揮還好, 看起來210. Day1看起來只有170, 不知道還會不會再出問題.
            Ylen神牛貌似寫了230 + 210, wx神牛可能500+, xh裸考看起來都和我成績差不多....
            看了WJMZBMR神牛的題解, 三題做法一樣, 有些心安. 看了貼吧, 發現某題某種邊界情況沒有測試, 細想了一下好像沒問題.
            本來挺淡定的, 頹了一個下午又心慌了. 還有不少作業, 還是不能頹啊.

            posted @ 2011-11-14 19:33 Climber.pI 閱讀(374) | 評論 (0)編輯 收藏

            Problem List(10.29 ~ 11.12)

            10.29

            WZOI第一次模擬賽, 2h -> 0
            卡第一題, 現在頭暈中. 思路錯誤, 很快的得到了題意, 對斐波那契數列取模. 然后用特征方程搞出了遞推式, 然后發現n>=20后的情況, 嘗試對無理數取模, 然后各種頭暈.
            *這是NOIp, 不是CMOp, 怎么會考這么蛋疼的東西. 找時間重寫吧, 限時2.5h. -> 應該往周期數列的方向上想
            *感覺現在需要系統復習, 又是瓶頸狀態

            10.30

            調教Ubuntu in VMware, TeX中文無能

            姜碧野論文<SPFA算法的優化及其應用>, 學習差分約束系統
            *還有兩種優化SLF和LLL, 真心覺得不如打dij+heap

            butter, 復習SPFA.
            *關于數據結構的整理
            (1)鄰接表 first/next/u/v/w/Cnt -> addEdge()
            (2)SPFA d/q/inq
            (3)初始化 first/d
            *沒有考慮雙向邊, 不可達的情況. 在敲代碼之前應盡可能完善算法.

            poj3259[DEC06, Gold, SPFA找負環]
            (1) BFS做法
            數組count[]記錄每個點的入隊次數, 由定義易知, 若count[i]>=N, 則圖必然存在負環.(<算法之道>上有個很好的例子)
            *標程直接按照Bellman-Ford的定義做, 復雜度O(NM). 網上的一次BFS的做法是錯的, 比如兩個強連通分量的情況:
            1
            6 4 2
            1 2 2
            1 3 2
            2 3 2
            4 5 2
            5 6 10
            6 4 10
            *因而N次SPFA的效率O(kNM)可能不如裸的Bellman-Ford O(NM); 更好的做法是Tarjan+SPFA, 即只對每個強連通分量進行SPFA, O(N + kM) 
            *優化: 
            1) d[]可以初始化為0, 速度比(3)要快
            2) 入隊次數不超過2(M+N), 可能錯誤
            (2) DFS做法, WC09姜碧野論文涉及, 實現無能.(網上的做法又是錯的)
            (3) Bellman-ford, O(VE)
            三重循環, 對每條邊更新V次, 效果好于(1)
            *SPFA找負環, 利用vis標記每個點是否被訪問過, 僅對當前未訪問的點進行SPFA, 這樣的話效率應該高于O(VE) //期望情況下

            10.31

            poj1201[差分約束系統], 25min, 1Y //參見WC06馮威論文
            關鍵在于建模, 令d(i)表示0..i的整數個數, 可得
            d(b) - d(a-1) >= c_i
            d(i) - d(i-1) >= 0
            d(i-1) - d(i) >= -1
            w(a-1, b) = c_i
            w(i-1, i) = 0
            w(i, i-1) = -1
            按照定義, 求整數個數最小值, 即求SPFA最長路.
            *注意更新最小標號idS, 最大標號idE, 第二類邊要對1..idE的情況賦值
            *關鍵在于找出差分方程組
            http://blog.csdn.net/kk303/article/details/6864199
            *一般的解題步驟: (1)建模 (2)設計數據結構 (3)寫出大致流程

            po3169[差分約束系統], 35AC, 3WA
            (1) 建模
            題目中給出兩種邊(a, b) , d
            對于第一種, (a, b) >= d
            對于第二種, (a, b) <= d, 即(b, a) >= d
            *SPFA求最短路, 還是最長路, 由不等號方向決定
            (2) 討論各種解的情況
            1) 正常
            2) -1, 存在負環
            3) -2, 無法連通
            *對于負環, 小范圍Bellman-Ford(多進行一輪松弛操作), 大范圍一次SPFA(count[i]>=N)
            *各種字母打錯, 變量打錯 -> 對于點, MAXn; 對于邊, MAXEdge;

            東方幻想鄉Stage2, P4, suika[分層圖最短路+SPFA], 1h
            (1) 建圖
            1) 點從奇時刻到偶時刻(U,U'), 從偶時刻到奇時刻(U',U)
            *需要注意黑洞停留消耗體力s[U], 白洞不消耗
            2) 邊, 兩種情況
            A. 端點顏色&重量相異(正負號取決于題意)
            奇時刻到偶時刻 (U, V') = w(U, V) ± delta
            偶時刻到奇時刻 (U', V) = w(U, V) ± delta
            B. 端點顏色相同/重量相同
            奇時刻到偶時刻 (U, V') = w(U, V)
            偶時刻到奇時刻 (U', V) = w(U, V)
            (2) SPFA最短路
            *注意讀題(題意/算法流程/數據結構)
            *Nettle標程的做法, 規定2*U為偶時刻點, 2*U-1為奇時刻點, SPFA起點由起點狀態決定. 可以避免建圖時的討論.
            *算法三依舊理解不能.

            NOIp09, trade
            (1) 傳遞閉包+枚舉, 40
            1) O(kN^3), 利用鄰接矩陣更新連通性
            2) O(N^2), 對每個點找最大旅費, max{w[i] - min{w[j]}} ((j,i) (1,j) (i,N)連通)即為答案
            (2) 兩次SPFA維護連通性+枚舉, AC
            1) 從起點1開始SPFA, d[i]表示(1,i)是否連通; 
            A. 對于正環的處理
            按照定義, count[i]>=N則不再入隊.(這樣70, 利用r<=2*N不再入隊可以AC)
            B. 記錄遇到的最小價值Min{A[j]}
            2) 從終點N開始SPFA, 將之前的邊反向(添邊時使用last和prev數組, 替代first和next數組), 維護連通性
            3) 枚舉min{A[i] - min{A[j}}, (j,i)連通, 1<=i<=N的最大值即為答案.
            *題解給出了兩種做法
            (1) 求強連通分量縮點, 轉化為DAG, 然后求解
            (2) d[i] = min{d[i], d[j], a[j]}作為松弛操作, SPFA

            SPFA專題結束, 明天開始Tarjan和dij+heap

            11.1

            agrinet[Kruskal], 20min, 復習Kruskal

            11.2

            Tyvj, Sept09, P2[Kruskal + 并查集]
            需要理解Kruskal的過程, 做法如下:
            (1) 間接排序(邊集數組)
            (2) 按照Kruskal, 從w[i]最小的邊開始統計,并查集維護聯通性
            p[x] = y;//并集
            num[y] += num[x];//統計每個集合的點的個數
            maxe[y] = max{maxe[y], maxe[x], w[i]};//維護每個集合的最大邊
            ans += (C(2,num[x]+num[y]) - C(2,num[x]) - C(2,num[y]) - 1) * (maxe[y] + 1);//統計沒有聯通的邊
            *沒有間接排序WA了一次,可以通過小數據檢驗(比如深度不同的樹、鏈)
            *各種卡long long, 可以計算最大值為10^6C(2,10^6)
            -> long long的類型轉換, long long類型的計算中, 數字必須標識ll, 否則會導致計算錯誤.(也就是說可能爆int范圍的地方都要用long long)
            -> [by gXX] 可以這么分析, (long long) = (int) * (int) / (int); 于是中間的寄存器會掛掉
            *深度大于1的樹的生成 by Ylen
            和深度為1的樹的做法相同, 然后記錄葉節點, 對葉節點隨機伸長

            NOIp10, P3[并查集]
            *需要明確并查集能干什么, 并查集可以合并, 但是不能隔開 -> 把分隔操作轉化為合并操作
            (1) 間接排序(邊集數組)
            (2) 利用sep[i]記錄i的敵人, 對于(u,v)
            i) sep[u]存在, 那么merge(v, sep[u]) //u的敵人們是朋友
            ii) sep[u]不存在, 那么sep[u] = v//v是u的敵人
            v同理, 遇到find(u) == find(v)的情況, 直接輸出答案即可
            *需要注意特判沖突的情況, 不妨用flag標記, 若沒有輸出答案, 則輸出0

            王曉東練習題, 序關系計數[DP]
            f(i, j) = (j+1) * (f(i-1, j-1) + f(i-1, j))
            f(i-1, j)很好解釋, f(i-1, j-1)解釋無能
            [狀態]f[i][j]表示i個數加j個小于號
            *Covi給出一個結論, 禁止小于號加在一堆等號內部, 證明無能 -> 在zjy的提示下解決了
            *注意到序列中已添加的數的值是不變的
            i)f[i-1][j]的話, 已有的數被分成j+1組, 顯然每組只能添加1個等號
            ii)f[i-1][j-1]的話, 已有的數被分成j組, 因為要添加<號, 所以只有(j-1)+2=j+1個位置可以(即每組的邊界)

            Contest OPEN11 Silver, llang[并查集]
            (1) 讀入分別以 奶牛 和 語言 為關鍵字, 用鄰接矩陣存儲(這里必須用到vector)
            (2) 合并說相同語言的牛, 得到m個集合, m-1即為最少數量
            (3) 遍歷N個點, 若該節點所在集合未被遍歷, 則標記遍歷并輸出
            *vector的用法: 非常適合稀疏圖的鄰接表的數組實現
            (0) 聲明變量: vector<int> A;
            (1) 加入元素: A[i].push_back(elect);
            (2) 獲取某列元素個數: A[i].size();
            (3) 獲取某個具體元素: A[i][j] //0 <= j < A[i].size(), 注意范圍

            還有一道kruskal和兩道tarjan以及dij+heap

            11.3

            NOIp07真題, 3h, 300
            P1: 模擬, AC
            P2: 字符串, AC
            利用flag表示是否輸出(僅標記), 然后Expand函數三重循環即可.
            *考慮這種情況1-2-7, 以及A-B

            P3: DP, 90(本地壓四位后90)
            [狀態] f[k][i]表示當前行長度為k, 行首編號為i
            [方程] f[k][i] = max{f[k-1][i+1] + A[i] * 2^(L-k+1), f[k-1][i] + A[i+k-1] * 2^(L-k+1)}
            [初始化] f[1][1..N] = 2^L * A[i]
            *變量打混, 務必靜態查錯
            *高精度寫掛
            (1) 進位
            (2) 輸出0(去掉前導0的時候, 保證len>0)
            *print可以特判len<0輸出0
            (3) 雙目運算符必須const, 這是一個很好的習慣, 避免值發生不必要的改變; 
            *返回的bign盡量新建.
            *最大測試點, 本地0.9s, RQ0.4s, Tyvj0.0s

            P4: Floyd+亂搞, 50minAC(計時賽無分數)
            (1) Floyd求任意點最短路, 記錄最大值(即直徑)
            (2) 對d(i, j)=直徑的邊, 求路徑
            (3) 對于每個直徑, 求出它的所有路徑, 然后對每個路徑求其他點到此路徑的最大值(dist操作, 某點到此路徑的最小值)
            *點的情況需要特判
            *注意區分最大/最小值, 這題考的就是對于抽象模型的理解能力
            *有線性時間做法

            東方幻想鄉Stage2, P3, 60棧崩潰

            11.4 & 11.5

            叉姐模擬賽, 140/300
            P1: 字符串處理, 卡通配符含義, 30
            (1) 讀入, 可以利用數組+標記字符 或者 vector
                for (int i = 0; i < n; ++ i) {
                    begin[i] = sumLen;
                    scanf("%s", str + begin[i]); //給出字符串首指針
                    len[i] = strlen(str + begin[i]);
                    sumLen += len[i];
                }
            *str記錄字符串, begin記錄起始位置, len記錄長度
            *vector必須手工轉換, 不能直接利用scanf讀入
            (2) 標記*位置(初始化為strlen(p), 注意沒有*的情況)
            (3) 從起始位置掃描一次, 區間[0, pos)
            從終止位置掃描一次, 區間(pos, len-1]

            P2: 最大帶權生成樹, Kruskal變種. 寫了一個生成子集, 40
            [AC做法]
            (1) 判斷無解[鄰接表 + BFS]
            *注意變量名
            (2) 邊i的權值為w[A[i]] + w[B[i]], 根據度的定義容易得到.
            之后套用Kruskal, 降序排序即可.
            [40%做法]
            (0) 判斷無解
            (1) 位運算生成子集(N <= 20) -> 亦可DFS生成C(N-1, M)集合
            (2) BFS驗證連通性
            (3) 計算權值
            *一開始看錯范圍, 認為必須用O(N)算法, 然后不考慮排序. 權值最大 -> 度最大, 貪心無能.

            P3: 動態規劃, AC
            利用恒等式\sum{x_i * x_j} = 1/2(\sum{x_i}^2 - \sum{x_i ^ 2})
            可以通過觀察, 或者數學證明最值只在極值點取到.(60%算法, 直接枚舉)
            因而要求\sum{x_i * x_j}最小值, 即求\sum{x_i}^2的最小值
            \sum{x_i}的最小值, 可以對所有數進行容量為\sum{A_i}/2的0/1背包, \sum{A_i}/2 - 2 * f[\sum{A_i}/2]即為答案.
            *gXX給出了利用一次函數的證明方法, (待補)
            *對于此類數據類型誤導題目, 可以通過數學推導, 或者編程實驗證明.
            [標程做法] by ftiasch
            (1) 討論極值位置
            固定x_1, x_2, ..., x_{n - 1} .  
            f(x_n) = (x_1 + x_2 + ... + x_{n - 1}) * x_n + () ...  
            這是個關于x_n的一次函數, 所以只有在端點處才會有極值.
            x_1 * x_2 + (x_1 + x_2) * x_3 + (x_1 + x_2 + x_3) * x_4 + ...  
            (2) DP
            dp[i][j]表示前i個數, 在x_1 + x_2 + ... + x_i = j的情況下的答案, 轉移就是枚舉現在是弄個+a_i還是-a_i。  


            NOIp06真題, 3h, 120 >_<
            P1: 環狀區間DP, 10
            (1) 方程
            f[i][j]表示合并第i顆珠子的頭標記到第j顆珠子的尾標記的最大值
            f[i][j] = max(f[i][k] + f[k][j] + A[i]*A[k]*A[j]) (i <= k <= j)
            (2) 實現
            改寫方程
            f[l][i]表示從i開始, 合并l顆珠子(指頭標記)的最大值
            f[l][i] = max(f[k][i] + f[l-k][i+k] + A[i]*A[i+k]*A[i+l]) (1 < k < l)
            *注意下標; i的枚舉范圍是[1, 2n-1], 環狀; -> 當成鏈做只有50
            *和一般的區間模型最大的不同, 在于頭尾標記, 事實上比較可行的方法是在草稿上按照要求畫出珠子, 以檢驗下標;

            P2: 簡化版孩子背包 -> 分組背包, AC
            *Nettle的某道模擬題和此題的命題思路如出一轍, 都有兩種做法, 一種是直接套用更復雜的模型, 另一種是改變現有模型. 要充分挖掘問題性質.

            P3: 模擬, 10
            (1) 找空擋
            從time[opt[k]][count[opt[k]]]開始
            驗證區間長度
            ++Time //這里類似字符串匹配
            (2) 在空擋標記時間
            (3) 更新完成時間, finish[opt[k]][count[opt[k]]] = Time + time[opt[k]][count[opt[k]]] - 1;
            (4) 更新最后完成時間
            *一定要在草稿紙上寫出流程和關鍵語句

            P4: 遞推, 沒時間, 6h
            題目中第二次描述給了很關鍵的暗示(看了BYVoid的題解豁然開朗, 捶胸頓足中):
            [狀態] f[i][j]表示i為2^k進制數最高位為j
            [方程] f[i][j] = \sum{f[i-1][m]} (j+1 <= m < 2^k)
            ans = \sum{f(m, 0)} (3 <= m <= w/k + 1) + \sum{f(w/k + 1, i)} (1 <= i < 2^(w%k)-1)
            *可以直接利用記憶化, calc[][]標記是否計算, int70, 高精90
            *由于題目的范圍很大, 考慮滾動數組(注意每次計算初始化), 遞推計算f[][], 累加同時進位, 高精度壓位, 大概第10個點1.35s. 去掉了運算符重載, 第10個點0.9s.
            *這題屬于典型卡常數, 賽場上, 能觀察出方程并調出70分即可, 時間充裕可以考慮調試90分.
            *注意運算符優先級(10)
            *高精度調試技巧
            (1) 初始化(初始化位置)
            (2) 進位(模擬手算)
            (3) const(防止修改不應修改的值)

            rqnoj 341[SPFA], 40min
            (1) 無向圖看成有向圖
            (2) 漏打循環隊列
            (3) first[]初始化錯位
            *草稿紙很重要!!!

            11.6

            叉姐模擬賽, 210/300
            P1: 2個trick, long long, 還有范圍
            P2: 0/1背包變形
            預處理, 以c[i] - v[i]為關鍵字升序排序
            P3: 二分圖判定
            *無向圖, 考慮兩條邊
            *描述歧義, 特判沒寫, 不說了, 浪費了2h

            NOI 2001 食物鏈[并查集], WA
            和之前的做法完全不同, 題目是環狀依賴.
            *尼瑪今天寫check.bat都不check..
            [題解]http://winterlegend.blog.hexun.com/25409221_d.html

            NOIp04 合并果子[小根堆, STL實現]
            學習STL中的優先隊列:
            [聲明] priority_queue<int, vector<int>, greater<int> > q;
            *小根堆, greater; 大根堆, less;
            [彈出隊首] q.top(); q.pop();
            [加入元素] q.push(k);

            ftiasch, 2010114模擬賽
            P1: NOIp10第三題, 判定二分圖
            P2: 找個兔子, 在不超過L的范圍斷開, 直接驗證
            P3: 把每個時刻的蘿卜加入堆(當前時刻沒有, 則添加下一時刻), 維護當前時刻最大值, 累加即可.
            P4: 最小生成樹 + 背包
            對于一條路(i, j), 需要消耗D(i, j)個同類型的蘿卜, 因而需要一次0/1背包.

            NOIp04 合并果子[小根堆, 手寫heap]
            堆只維護隊首元素最小值, 不對隊中其他元素負責.
            up() 直接上翻
            down() 盡量取2*k+1(目的就是找到最小值), 然后下翻

            11.7

            Contest MAR11 packdel[dij+heap], 1h
            (1) dij+heap元素出隊時, 標記已計算(done[k])
            (2) 手寫可以用cmp函數比較, 注意A[k]與k的區別

            叉姐模擬賽,
            *手工修正了50%的數據..什么狀況

            NOIp10, 引水入城[BFS+貪心+分析]
            *認真讀題, 題目僅考慮最下面一行是否有水, 卡了40min
            (1)無解, 30
            對第一行進行floodfill即可, 可以BFS實現
            (2)有解, M <= 10, 50, 25min
            二進制生成子集, 然后利用floodfill填充, 并判定是否滿足題意, 維護最小值即可
            (3)有解, AC, 2.5h
            [重要結論]有解當且僅當, 第一行某個城市流經最后一行城市的結果連續.(若不連續, 必然不滿足題意)
            因而可以將題目轉化為最少線段覆蓋問題.
            利用鄰接表維護當前點的線段(注意退化為點的情況), 貪心過程如下:
            1) 從L = 1開始, 對于(L, R), 維護最大的R_Max
            2) 更新L = R, R = R_Max+1(左閉右開區間)
            3) 重復以上步驟, 直到R > M
            *貪心問題, 以及和區間有關的問題不熟悉, 待閱<淺談信息學中的區間問題>
            *要在紙上寫出關鍵條件和大致算法流程以及語句, 不要把時間浪費在調試上

            待閱<淺談信息學中的區間問題>
            *閱畢, 涉及到了白書上三類區間問題

            11.8

            Tyvj1038[RMQ -> ST], 1.5h
            ST算法(RMQ問題, 離線算法, O(NlogN)建表, O(1)查詢)
            [狀態] f[i][j]表示從[i, i + 2^j - 1]的最值
            [方程] f[i][j] = max{f[i][j-1], f[i + 2^(j-1)][j-1]} (以j為階段; 1+(1<<j)<=N, 保證實際意義合法)
            [查詢] 對于區間[i, j], 令k = [log2(j-i+1)], 答案即為max{f[i][k], f[j - (1<<k) + 1][k]}
            *不要相信樣例的調試性, 寫make, 或者打小數據手算

            Tyvj1297[ST], 40min
            *log_2打錯, 不妨自己寫函數

            Tyvj國慶新賽制模擬賽, Day2P2, game[單調棧+ST], 1.5h
            (1) 單調棧, 維護L[i], 表示A[L[i]..i-1] <= A[i]
            while(A[L[i] - 1] < A[i])
            L[i] = L[L[i] - 1];
            (2)ST
            *檢查方程和查詢的寫法, 靜態調試, 別盲目做
            *認真讀題

            NOIp08, message[雙進程DP],50min
            [狀態]f[k][i][j]表示從(1,1), 兩人分別走到(i, k-i), (j, k-j)的最大值
            [方程]f[k][i][j] = max{f[k-1][i][j], f[k-1][i-1][j], f[k-1][i][j-1], f[k-1][i-1][j-1]} + A[i][k-i] + A[j][k-j] (i != j)
            [答案]max{f[M+N][M-1][M], f[M+N][M][M-1]}
            *注意狀態的實際意義
            *注意不要隨便用簡化寫法, 事實上簡化寫法是最可能出問題的地方

            Tyvj國慶新賽制模擬賽, Day1P3, maze1[雙進程DP], 1h
            *注意讀題, 每個格子可能有不只一個面包圈
            方程和上一題一樣, 說一下如何記錄方案:
            利用數組t1[k][i][j], t2[k][i][j]分別表示兩個人走的途中可以吃到的最多的面包圈, 答案在其中取最大值即可. 標程把對每個格子面包圈的個數的計算加入了方程中, 從而避免了討論.
            *這兩天做陳題發現問題, 由于對于題目殘存的印象導致的讀題問題非常多.

            Tyvj國慶新賽制模擬賽, Day2P1, ship[計算幾何], 15min
            典型的卡讀題的題目, 穩定的定義是, 正多邊形的幾何重心落在最高的柱子們構成的多邊形中(不能在邊界).
            直接檢查下標即可, 連續兩最高柱子的下標只差小于(N+1)/2

            Tyvj國慶新賽制模擬賽,Day2P3, maze2[二分+BFS]
            *學習了白書上的二分查找上下界的方法, 并注意到是左閉右開區間.
            -> 按照當時帖子的說法, 標程錯誤, 修正一處后仍然WA.

            11.9

            叉姐模擬賽Stage4, 50 + 40 + 0 >_<
            P1: 高精度
            裸的高精度. 自己寫個30%算法跑一下可以發現, f[A][B] = A*B-1(好吧那個奇葩的遞推式怎么YY出來的)
            *三處寫掛: (1)數組范圍 (2)len的計算(乘法和加法不同, 要命的是還手工屏蔽了小數據) (3)進位(其實不需要特判)
            *一句話總結高精度寫法
            [加法]更新位值, 累加, 進位, 退位
            [乘法]更新位值(不同), 累乘, 進位, 退位
            *注意的情況, 進位(比如10)
            [背景]其實是有塊a * b的巧克力, 你要把他掰成1 * 1的巧克力, 求要掰多少次

            P2: 枚舉
            [關鍵結論]值最小的聚集點一定在某個點的x上, 某個點的y上(可以考慮證明一維的情況, 然后推廣)
            *昨晚的討論不充分, 錯誤的認為值最小的聚集點一定和某個點重合, 且任意多點在某點聚集等價(事實上僅在兩點的時候成立, 今天發現30%程序是錯的)
            然后枚舉每個x,y, 計算每個點和他們的曼哈頓距離, 排序后累加前k個, 維護最小值.
            復雜度大概是O(N^2 * NlogN)
            *改寫程序務必注意循環變量是否打錯

            P3: DP
            *現場的時候NC了, 寫了一個DFS, 大概能處理N <= 8的情況
            (1) 50%做法
            [狀態]f[i][j][k]表示取到A[i], B[j], C[k]的最小值
            [方程]f[i][j][k] = min{f[i-1][j][k] + A[i]*p, f[i][j-1][k] + B[j]*p, f[i][j][k-1] + C[k]*p} (p = i+j+k)
            [初始化]f[0][0][0] = 0;
            (2) 100%做法
            [狀態]f[i][j]表示取到A[i], B[j]的最小值
            [方程]f[i][j] = min{f[i-1][j] + A[i]*p, f[i][j-1] + B[j]*p} (p = i+j)
            [初始化]f[0][0] = 0;
            [記錄方案]按照f[i][j] == f[i-1][j] + A[i]*p倒推, 循環即可, 注意邊界.
            *直接記錄t[i][j] = i的話, 需要注意i==j的情況, 這里應該按照方程的實際轉移處理, 而這樣的情況很多, 所以沒必要使用;
            *先對序列A,B進行一次DP, 得到A和B合并后的序列D, 然后對C,D進行DP, 即可得到結果
            *想不出來的題目可以敲暴力觀察, 或者畫畫圖; 暴力程序一定要寫, 一方面啟發思路, 另一方面驗證正確性.

            叉姐模擬賽Stage3, 20 + 60 + 0 >_<
            *從哪里跌倒要從哪里爬起來...
            P1: 模擬, 求外表面積(不考慮內部表面積)
            [1] 對每個立方體的邊界染色, 然后從六個面逼近
            *對于有洞的情況會掛, gXX表示不會, 原因不知.
            [2] 正確做法
            (1) 對每個立方體的邊界染色, 維護最大坐標
            (2) 從(0, 0, 0)開始BFS,
            i, 已染色的點不標記已讀(遇到的Cnt++, 但不入隊)
            ii, 未染色的點標記已讀
            *標程范圍開小, 已經更新數據

            P2: 枚舉
            考慮僅有三個數的情況:
            操作前a, b, c 差分為(b-a, c-b)
            操作后a, a+c-b, c差分為(c-b, b-a)
            可以發現操作的實質就是交換差分.
            不妨設d[i] = A[i+1] - A[i],
            那么A[i] = A[1] + \sum{A[j]}(1 <= j < i)
            即\sum{A[i]} = N*A[1] + \sum{d[i] * (N-i)}(1 <= i < N)
            *注意范圍會爆int, 要用long long; 注意下標;

            P3: 查找中位數[數據已修正]
            (1)60%做法
            對每個區間復制一次, 然后qsort
            (2)AC做法 by gXX, 實現無能
            大意就是想把所有區間的中位數搞出來。其實可以用堆吧?
            就是枚舉一個左端點, 一個一個往里面加, 然后用兩個堆來維護中位數。就是一個最大堆一個最小堆, 然后不斷丟來丟去的過程。  
            呃。大概就是相當于要維護第k大這樣的吧。開一個最小堆, 里面只有k個元素, 而且是最大的k個, 然后其他的丟到最大堆里面。
            然后當你k要增大的時候,就把最大堆的堆頂拿過來。要減小的話, 就把最小堆的堆頂丟過去。
            就是這個意思, 此消彼長, 道法自然。

            11.10

            NOIp09 靶形數獨[DFS+剪枝]
            *手工指定搜索順序, 1.5h調試無能
            *題目中不考慮對角線, 手工順序無效!!!
            利用frist[][], second[][], grid[][]分別表示每個行/列/小九宮格的填數情況, countX[], countY[]統計一開始行列的填充情況.
            (1) BFS生成score[][]
            (2) 讀入數獨, 統計countX[], conutY[], 記錄填充情況
            (3) 對countX[], countY[]進行降序間接排序
            (4) DFS, 狀態DFS(x, y, sum)
            1) x == N+1, 統計答案
            2) y == N+1, 換行
            3) (x, y)已填充, 更新sum
            4) 枚舉A[mapX[x]][mapY[y]], 所有涉及值的地方按照map_[]順序
            *[動機]不必要的枚舉量, 優化搜索順序
            *90%的測試點在1s內, 1h內可以調試完

            NOIp04 蟲食算[DFS+剪枝], N h
            *注意讀題, 是N進制加法, 每個字母代表的數字不同
            (1) 70分做法
            DFS枚舉序列1..N代表的數字, 利用used[]判斷當前數字是否使用過
            [剪枝]對于豎式上同一列的三個數a,b,c, 顯然滿足c - (a+b) < 2
            *注意各種回溯細節
            (2) 80分做法
            對每一位進行枚舉, 判重和可行性剪枝
            *回溯只需一解的情況下, 要注意恢復修改值的時間
            *進位要用delta記錄, 可能出現多次進位的情況
            *else和if的匹配錯誤, 注意花括號!!!!!!!!
            *70分做法的剪枝用了沒效果, 網上還有一個剪枝, 同一列三數知二的情況下, 看剩下那個數的兩種情況能否使用, 可能可以AC

            東方幻想鄉Stage1P4[強連通分量, kosaraju實現], 40min
            (1) 正向對每個點進行DFS, 搜索完該點后加蓋時間戳
            (2) 邊反向, 按照時間戳逆序DFS, 標記根節點
            *NOIp09第三題用了類似的邊反向的做法

            WZOIStage2 P2[SPFA], 20min
            范圍很大, 題解給出的AC做法是DAG的DP,事實上SPFA可以AC.

            11.12

            敲Day1P2三種版本, 實測ST+鄰接表, N <= 30000; 裸的做法, N <= 15000

            posted @ 2011-11-14 19:14 Climber.pI 閱讀(402) | 評論 (0)編輯 收藏

            Problem List (10.1 ~ 10.27)

            10.1

            tyvj迎國慶新賽制模擬賽, 140min, 預計260

            excel[模擬], 50min, 預計AC
            直接模擬, 需要用康托展開. 可以打表判斷位數(利用等比數列求和).
            *注意考慮R C的順序

            stock[判斷有向圖連通性], 30min, 預計60/100, O(N^2*T)
            給出N個點, T條邊, 判斷至多添加多少條邊圖仍是DAG.
            對于每條邊(u,v), 利用DFS染色+鄰接表判斷(v,u)是否可達.

            maze1[雙進程DP+輸出方案], 60min, 預計AC, O(N^3)
            [狀態] f[x1][y1][x2][y2]表示從(1,1)兩人走到(x1,y2)和(x2,y2)可以得到的最多的面包圈.
                   t[x1][y1][x2][y2]表示從(1,1)走到(x1, y1)某人可以得到的最多的面包圈(題目要求最小字典序)
              G[x_][y_]表示(x_,y_)是否有面包圈
            *注意到(x1,y1)和(x2,y2)地位平等, 故只考慮其中一個即可.
            f[x1][y1][x2][y2] = max{f[x1-1][y1][x2-1][y2], f[x1-1][y2][x2][y2-1], f[x1][y1-1][x2-1][y2], f[x1][y1-1][x2][y2-1]} + G[x1][y1] + G[x2][y2]
            t[x1][y1][x2][y2] = max{t[x1-1][y1][x2-1][y2], t[x1-1][y2][x2][y2-1], t[x1][y1-1][x2-1][y2], t[x1][y1-1][x2][y2-1]} + G[x1][y1]

            NOIp09 Hankson的趣味題[數論], 1.5h, O(50000N), AC
            注意到最大公約數最小公倍數的性質就是
            a = p1^a1*p2^a2…pn^an
            a = p1^b1*p2^b2…pn^bn
            gcd(a,b) = p1^min(a1,b1)*p2^min(a2,b2)…pn^min(an,bn)
            lcm(a,b) = p1^max(a1,b1)*p2^max(a2,b2)…pn^max(an,bn)
            這里去年就想到了, 然后去年實現無能. 下面對每個因子p進行討論
            (1)對于min{p_x, p_a0} = p_a1
              i)若p_a0 = p_a1, 那么p_x ∈ [p_a1, ∞)
             ii)若p_a0 > p_a1, 那么p_x = p_a1
            (2)對于max{p_x, p_b0} = p_b1
              i)若p_b0 = p_b1, 那么p_x ∈ [0, p_b1]
             ii)若p_b0 < p_b1, 那么p_x = p_b1
            利用篩法構造小于√(2e9)的素數表, 對a0, a1, b0, b1分解質因數, 然后分別討論四種情況即可(乘法原理).
            *需要注意存在大于√(2e9)的素因子的情況, 利用b0[0]和b1[0]記錄即可, 需要注意b1|b0, ans*=2
            *利用factor函數分解質因數時, 傳遞數組指針, 此時不能在函數內對數組賦初值, 原因不知.
            -> size (int *) = 4, 即一個內存地址的大小, sizeof(char*) = 4. 因而只能利用循環賦值. by gXX
            [另解]把b1分解質因數, 然后用質因數枚舉b1的所有約數, 然后挨個求與a0的最大公約數和與b0的最小公倍數.

            10.2

            tyvj迎國慶新賽制模擬賽, 160min, 預計150 -> 60/110
            60min時讀題結束(大概開場25min才開始看題)

            ship[雜題], 84min, 預計?
            [題意]給定一個正n邊形, 在每個頂點上放高度不同的柱子, 使得高度最高的柱子構成的多邊形的重心落在多邊形內.
            1. 所有柱子同高顯然符合條件
            2. 高度最高的柱子構成正多邊形同樣符合條件, 即重心和正n邊形重合
            3. 重心不和正n邊形重合且不在邊界上, 判斷無能
            *需要注意的是2和3, 在看了coderspace的答疑之后才想到.

            game[模擬_60/], 160min, 預計?
            "他就要從自己從左邊記下的數字和從右邊記下的數字中分別選取一個數, 將大的減去小的并大聲喊出來."
            ->O(N^2), 60
            對于每個小朋友, 向左向右記錄符合條件的最值. 如果兩邊同時記錄了最值, 那么輸出max{MaxL-MinR, MaxR-MinL}. 否則輸出-1.
            *這題讀錯很多次, 一開始的想法并不正確, 之后有認為是最長不下降子序列, 并復習了O(NlogN)做法. 但事實上符合條件的序列不是單調的. 需要在紙上抽象出條件.

            maze2[二分+floodfill/], 120min, 預計AC
            [題意]從(1,1)到(n,m)存在一條路, 使得途中的曼哈頓距離k最大.
            對于每個k, 第一次floodfill表示c個面包圈附近所有曼哈頓距離d<=k的點. 然后從(1,1)進行第二次floodfill, 已標記的點不能通過, 若可以到的(m,n)則滿足題意.
            *需要注意可以從上下左右任意方向走, 只通過右下方向會忽略很多情況.(by coderspace)
            *這題是gXX出的, gXX表示標準做法不是二分

            tyvj迎國慶新賽制模擬賽[170/600] -> 各種問題亟待解決

            10.17
            [BYVoid Stage1] 3h + 2.5h, 位置值25%
            寫了2h, 前兩題預計AC, 第三題滿分算法需要遞推式, 70%算法看不出來; 第四題類似OPEN11的第一題, 各種心理陰影. 第二題花了20min練習對拍.
            [summary], 130 = 10 + 100 + 10 + 10;

            P1: BFS染色看成DFS染色, 需要注意更新條件(G[kx][ky] > G[x][y]+1), 否則會超時 -> 涉及最短路徑的問題顯然是BFS, DFS會造成各種奇葩的問題
            *事實上還是腦抽了, 標準做法O(MN), 將所有傳染源加入隊列, 直接BFS即可.

            P2: 分組背包問題, 差點看成泛化物品. 數據很弱, 用來對拍的暴搜同樣AC.
            *O(ABN), 和標準做法一樣, 而且利用了0/1背包的性質直接降維, 減少內存使用.

            P3: 看了題解, 收獲很多.
            (1)從數學角度考慮, 70
            不妨考慮題目的退化情況, 即不存在棧元素數量p的限制. 注意到1號元素比較特殊, 初始時1號元素必須先行進入b棧, 然后進入c棧. 故而可以劃分為兩個過程, 過程I在a元素進入c棧之前, 過程II在a元素進入c棧之后. 利用乘法原理f[n] = Σf[k]*f[n-k-1](0<=k<i). 當然這東西其實就是Catalan數.
            *白書上給出了另一種推導方式, 利用凸多邊形上的分割. 固定一三角形V1VkVn, 討論其兩側的多邊形的情況, 故而f[n] = Σf[k][n-k+1](k>=2), f[2]=f[3]=1. 也可以通過固定對角線的方式討論, 注意到每條對角線被重復計算了2n-6次(凸n邊形僅有n-3條對角線), f[n] = Σf[k]*f[n-k+2]*n/(2n-6). 與上式聯立可知, f[n+1] = f[n]*(4n-6)/n.
            *這里的推導方法和第二類stirling數的推導方式類似, 考慮一個特殊元素的動作, 然后劃分問題(利用乘法原理).
            加上棧元素數量的限制, f(i,j)表示i個元素在棧元素限制為j時的方法數, 可得f[n][p] = Σf[k][p-1]*f[n-k-1][p](0<=k<n), f[i][0] = 0(0<i<=n), f[0][j] = 1(0<=j<=n)
            (2)從動態規劃角度考慮, AC
            考慮到題目中存在三個棧a\b\c, 設置狀態為f(i,j,k)表示a棧中有i個元素, b棧中有j個元素, c棧中有k個元素的方法數, 注意到i+j+k=n, 故只用f(i,j)即可.
            若a棧中有i個元素, b棧中有j個元素, 可能是a棧中的1個元素到b棧中, 亦可能是b棧中一個元素到c棧中, 故而方程為f[i][j] = f[i+1][j-1] + f[i][j+1], f[n][0] = 1, f(0,0)為所求. 這個方程應該同樣適用于無棧元素限制的情況(即沒有特別的限制).
            *數學上的遞推式的思考方式, 往往是固定或者討論1個元素, 進而劃分問題或者類似情況. 而DP的思考方式, 建立在狀態的基礎上, 注重狀態間的轉移, 進而找到方程.
            *一個小技巧, a mod 2^p = a & (2^p-1); 直觀上其實很容易理解, 轉化為2進制看待, 取模即得到a二進制下得后p位, 和位運算與的目的是一樣的.

            P4: 需要抽象出最短路模型, SPFA即可.(注意此時的點數不超過p*p, 而不是p)
            注意到題目中同種能量結界可以無損耗傳送, 不妨將每個能量結界縮為一點, 于是可以得到一個新的圖. 為了簡化計算, 在第一行前增加起點, 在最后一行后增加終點. 求出從起點到終點的最小點權覆蓋即為答案. 然后題解中給出了一種很神奇的構造, 將起點和終點外的點形成的邊拆成兩個邊, 邊權為邊終點的點權, 起點和終點僅考慮單向. 利用鄰接表實現, 可以利用一個bool型數組判重. 之后利用SPFA求最短路, h-d[p+1]即為答案, 小于0輸出NO.
            *關鍵在于1) 以能量結界為點抽象出圖, 轉化為最小點權覆蓋.
            2) 拆邊賦權, 轉化為最短路模型.

            10.18

            USACO Contest OPEN11 cornmaze(BFS), 2h
            略復雜的BFS, 寫了約30min, 調了1.5h. 主要卡在兩個錯誤和STL的語法上.
            按照題意, 從起點開始, 如果遇到裝置直接跳, 遇到草地繼續走, 遇到玉米就終止, 直接BFS即可. 注意到題目中的裝置成對出現, 而且遇到裝置必須走, 這和昨天的第四題不同. 可以利用map數組記錄裝置的對應關系.
            *對于一對裝置, 從A到B, 只需標記A已讀, 無需標記B已讀, 可能出現跳過來又跳回去更短的情況. 但是要使B入隊, 并且更新B的距離, 而不是更新A的距離.
            *利用x*n+y對坐標編碼的時候, 充要條件是n>=m, 否則解碼會出現錯誤. 因而可以利用x*(n*m)+y進行編碼, 在不溢出int的情況下. 當時在白書上見到這種寫法, n=m, 并且坐標從0開始.

            10.19

            Tyvj新賽制模擬賽 stock, unAC.

            10.20

            stock[傳遞閉包]
            題意就是確保每條需要添加的邊(x,y), (y,x)不連通, 且x!=y(即點上沒有自環).
            和wx神牛給出的做法一樣, 維護一個N*N的矩陣表示連通性, 若加入邊(x,y), 則更新x的前驅和與y的后繼的集合(x,y分別在集合中)的邊為連通.
            *復習了對拍的寫法, 昨天查錯查了1h, 寫了O(N^2*T)的寫法:
             (1)更改了已連通點的情況
             (2)沒有考慮x的前驅和y的后繼直接連通的情況
             (3)沒有考慮點的自環(make中人為避免了這種情況, 審題不清.)
            *參照題解寫O(NT), 更新連通情況時G[A[i]][B[j]]打成G[A[i]][B[i]], 對拍后發現.
            *當時的DFS寫法的問題, 修正后50:
             (1)沒有考慮重邊的情況, 因而對于每一條邊都要重新加入, 數組必然會爆. 可以利用矩陣維護已添邊, 這樣的話復雜度應該為O(N^2*P).
             (2)next[]數組范圍開小

            [BYVoid Stage2] 1.5h, 完全不會. -> 眼高手低
            以下是對于題意的簡單判斷, 看起來和去年差不多, 眼高手低:
            P1: 模擬, 但是概率無能
            P2: DP, 沒想出方程
            P3: DP + 多重背包?
            P4: 極大強連通分量, Tarjan忘了, 裸的做法不會(注意到范圍很小)
            -> 題解顯示方向判斷基本正確, 基本思路都正確, 但是實現都卡在某些地方

            P1:分為兩個部分, 求概率和期望, 有1個trick.
            對于概率可以分四個部分討論:
             (1) 無事故 -> 按照題意, 乘以無事故概率分別計算即可
             (2) 同時事故 -> 平局, 把四個獨立事件(故障)乘起來
             (3) 侏儒事故 -> 地精勝利, 地精無事故*侏儒事故概率  ->需要注意這里不需要考慮無事故獲勝概率, 仔細讀題
             (4) 地精事故 -> 侏儒勝利, 類似上文
            *需要注意利用pow(sum,1/n)開n次方的時候, 必須邊讀入邊計算, N = 1e6. 可以利用e^((1/n)*ln(a)) = a^(1/n)來計算.
            *沒有在分類基礎上結合題意繼續討論, 導致理解偏差, 于是沒想出來.

            P2:我想的方程的狀態是f(i,j)表示疲勞度為i, 行走距離為j, f(i,j)表示所需最小時間.
            所以方程 f(i,j) = min{f(i-1, j+1), f(i+2, j+5), f(i+5, j+10)} + 1 (i ≠ p)
             f(p-10, j+10) + 10 (i = p)
            以距離為階段, 沒有后效性, 看起來如果記憶化, f(0,0)是答案. 但min給初始化造成了一定的麻煩; 更重要的是, 這樣的方程使用滾動數組較為麻煩, 會爆內存.
            *事實上i == p的情況不會得到最優結果, 即干擾條件. 要避免疲勞度達到上限.
            改進做法是這樣, f(i,j)表示行走最大距離, i表示花費時間, j表示疲勞度, 可以得到方程:
            f(i, j) = max{f(i-1, j+1)+1, f(i-1, j-2)+5, f(i-1, j-5)+10}
            需要利用滾動數組降維, 即for(i = 1, k = 1; i <= S; i++, k = !k)
            *需要指出方程不太嚴謹, 考慮S=1, P=1, 條件1的1+1>P, 所以需要特殊處理.
            *太久沒寫DP了, 所以方程細節問題很多.

            10.22
            東方幻想鄉Stage1, 2.5h, 215 -> 310, 位置值65%
            *發現solution一個很好的用途, 比較命題人給出的題意, 鍛煉從題目中抽取信息的能力.

            P1: 模擬+分析, 20min, AC
            (1) 計算整個序列的位移向量a
            (2) T/len * a, T%len模擬
            *個人覺得亦可正交分解, 統計不同方向向量個數(N S對稱, W E對稱), 做法同上.

            P2: 二分高精除法, 1h, TLE原因不知
            *[沒有注意到范圍] O(LlogANS), 題目中給的ANS<=2*1e9, 而我算的ANS是1e20000. 本來是20000*9, 范圍錯誤后, 20000*20000, 顯然TLE.
            *按位除效率高于二分高精除 by qz神牛
            *其實直接寫單精度乘法即可
            *題解中二分條件, left+1<right;left = mid;right = mid;
            *INT_MAX的另一種寫法, ~0U>>1, U表示無符號整數 by WJMZBMR

            P3: DP+優化(單調隊列\優先隊列), 60
            f[i]表示在i取得的最大冰凍指數值
            f[i] = max{f[i-j] + A[i]}(L<=j<=R, 0<=i<=n+R)
            利用prev[i]記錄f[i]由f[i-j]推得, 遞歸即可記錄方案.
            *2個trick, 存在負數(初始化-INF), 可以越過終點(前驅必須在終點前) -> 注意數組大小為f[N+R], 否則溢出

            P4: 強連通分量(Floyd傳遞閉包+并查集), 50
            利用Floyd傳遞閉包, 對于每一點對(u,v), 若是雙向連通則使用并查集合并集合{u},{v}. 統計元素數最多Max的集合, 從頭開始掃面每個節點所屬集合, 遇到所屬集合元素數量為Max的點直接跳出. 掃描該集合即可輸出方案.

            10.23

            toj 1169 廣告印刷[單調隊列]
            NOI導刊(11.5)例題, 使得隊列中元素大小和下標同時單調. TLE, 原因未知.

            [東方幻想鄉S1P2]iceroad, DP+單調隊列, AC
            維護區間[i-R, i-L]的最大值, 先檢查隊列中元素下標的合法性(即滿足q[head]>=i-R), 然后插入元素f[i-L].
            *越過終點的情況必須初始化A[], 否則會造成答案錯誤.
            *按照std, 必須初始化為0, 否則最后兩個點WA. -> 數組溢出, 必須初始化為-INF, 數據弱, wagner的std會掛
            *對于大數據掛掉的情況, 很可能是由于數組溢出

            [東方幻想鄉S1P3]classroom, Floyd+并查集, 60
            (1) 一個錯誤,如果存在邊(v,u)會被刪除.
            G[v][u] = (type == 2) ? 1 : 0; -> 考慮之前存在邊(u, v)
            *縮略形式很可能是不等價的, 要考慮全面
            (2) 記錄集合元素個數的寫法
            path[y] = path[x];
            tot[x] += tot[y];
            可以這么解釋, find(y)會指向x, 于是更新x的元素個數.
            *想起了Tyvj9月月賽第二題

            10.24
            東方幻想鄉Stage2, 2.5h, 200, 位置值82%
            P1: 簡化版最大子矩陣, AC.
            給出了矩陣大小(R,C), 令s[i][j]表示Σs[1..i][1..j], 只需枚舉[R,N, C,M]作為矩陣頂點計算大小即可.
            s[i][j] = s[i][j-1] + s[i-1][j] - s[i-1][j-1] + A[i][j]
            矩陣大小S = s[i][j] - s[i][j-C] - s[i-R][j] + s[i-R][j-C]

            P2: 進制轉換+同余, AC.
            (1) 得到1..L位分別對于M取余的余數pow[i]
            (2) O(L), 判斷當前數是否整除
            余數rem = Σs[L-i-1]*(A[i]-'A'), 利用傳遞性取余.
            (3) O(L^2), 枚舉任意兩個數對(i,j), 交換后計算余數, 若整除直接輸出結果
            題目要求字典序最小, 指字符串[1..L], 需要注意下標 -> 這里浪費了20min, 多次手工模擬錯誤
            交換的寫法:
            rem += M - ((s[i]-'A') * pow[L-i-1]) % M;//利用補數, 分別減去i,j原來的位值
            rem += ((s[j]-'A') * pow[L-i-1]) % M //加上i,j新的位值
            *Win7一個奇葩的性質, patchouli因為有關鍵詞patch, 會默認以管理員身份運行, 于是調試無能.

            P3: 似乎是計算幾何, 只想到了旋轉坐標系. -> 預處理[排序]+DP
            (1) 利用點斜式得到結論 d = y - kx, 以d為關鍵字對點進行排序
            (2) f[i]表示1..i點可以取到的最大值
            f[i] = max{f[j] + Σvalue[i]*Σmul[i]/(j-i) (這里Σ的范圍是[j-i+1, i])} (0<j<i)
            *對于α=90°的情況, 由于π的精度不夠, 可以不討論. -> 對x排序即可, 實現的話可以直接交換坐標
            *對于多點d相同的情況, 按solution寫法應該討論, 但是參照標程特判會WA, 原因未知?

            P4: 圖論題, 有條件的最短路問題.
            *分層圖最短路


            10.27

            東方幻想鄉Stage3, 2.5h, 110, 位置值64%
            *心不在焉, 多次看錯題.
            *需要思考看完整套題的意義, 目的是什么, 需要得到什么樣的信息.

            P1: 二分+模擬, 95
            (1) 記錄被破壞點下一個被破壞點的位置next[]
            (2) 以0為下界, [N/K]+1為上界, 二分答案L -> L=0即未被地震破壞, 考慮不周
            (3) 利用next[]對數軸染色, 限制次數為K, 若染色后仍發現破壞點則無解

            P2: 概率, 15, O(NT) -> 正解是DP
            每個時刻更新每個點的概率, 利用鄰接表(矩陣實現). 不更新的充要條件是vis[v][u][k-1]=1.
            用P[i][k]表示第i個點在第k時刻的概率, 初始化P[1][0] = 100.
            *思路非常混亂, 一開始不更新的充要條件找錯. 錯誤原因不知.
            *不明白O(NT)的做法為什么會錯, 標程用類似樹形DP.

            P3: 最小生成樹+并查集維護連通性+枚舉 -> 不用并查集
            利用Kruskal構造最小生成樹, 并查集記錄連通情況, 利用鄰接矩陣維護, 枚舉每個度大于2的點不斷按照定義更新答案.
            *考慮到多邊權重相等的情況, 可能需要多次計算.

            P4: LCS? -> 搜索+剪枝

            posted @ 2011-11-05 14:05 Climber.pI 閱讀(226) | 評論 (0)編輯 收藏

            NOI Linux+VMware 安裝手記

            之前用Sun Virtual Box裝了新的NOI Linux,Ubuntu的版本新了好多,界面感覺不錯。感覺閹割了非常多的東西,比如OpenOffice,昨天下的rpm安裝無能。把涉及的幾個問題整理一下,如下:
            (1)如何讓Ubuntu和Win7共享文件
            VBox下沒解決這個問題,之前用sudo居然不知道密碼不會顯示。于是轉戰VMware,然后網速不太給力,下了一個下午。晚上基本弄好。主要是權限問題,必須在terminal下運行VMtools才可以。
            【基本參考這里】http://blog.sina.com.cn/s/blog_726684020100r1os.html
            【以下轉載】

            step1.安裝vmtools for linux:

            選擇VM >Reinstall VMware tools...

            之后虛擬機中ubuntu桌面出現VMware Tools的光盤符號

            在ubuntu里輸入以下命令(使用root帳號)

            mkdir  /mnt/cdrom
            mount /dev/cdrom /mnt/cdrom

            cd /mnt/cdrom

            tar -zxvf VMwareTools-8.1.3-203739.tar.gz -C /tmp

            cd /tmp/vmware-tools-distrib
            ./vmware-install.pl

            然后一路回車,要等一段時間才能安裝完畢。

            查看安裝后情況,使用以下命令:
            lsmod

            step2.設置共享目錄: 選擇VM>Settings>Options>Shared Folders

            step3.在ubuntu中查看共享目錄 
            輸入以下命令
            cd /mnt/hgfs
            ls
            可以看到win7系統中共享的目錄。


            (2)如何打開MSOffice文件

            可以去下載永中Office解壓后,在terminal下載安裝,進入目錄后運行./setup,可以看到圖形界面。注意主程序是精簡版的,其他四個部分需要分別安裝。

            這里的版本是2010。永中Office對于圖文并排的Word文檔支持不佳。


            (3)如何打開*.rar且顯示中文

            不要rar,在新立得中安裝unrar unrar-free

            *因為rar和7z是Win下的格式,因而需要手工處理。zip完全不存在這樣的問題。

            (4)Tex的安裝
            http://twntwn.info/blog/ajer001/archives/1728

            這陣子開始玩 LaTeX,果真是一個可怕的東西。現在正在努力的撈,紀錄一下安裝、CJK 環境等等。

            1. 安裝:

            sudo apt-get install texlive dvipdfmx cjk-latex

            這樣就可以了。如果還需要 IDE 介面:

            sudo apt-get install texmaker

            兩個東西很大,400+M,要下一陣子。

            1. 直接使用locale-gen
            在終端輸入命令:
            sudo locale-gen zh_CN.GB18030
            即可完成中文字符集的添加。完成后可以轉到

            /usr/lib/locale/,下面已經有一個zh_CN.gb18030文件夾;在超級終端輸入命令:

            gedit /var/lib/locales/supported.d/local,可以發現文件中多了一行:zh_CN.GB18030 GB18030。說明添加成功。



            (5)讓Texmaker支持中文
            http://hi.baidu.com/huaerzaikai/blog/item/8cc478b5c227b1c237d3cabd.html

            (6)一句話總結
            不要用VMware Player的自動安裝功能。
            linux的命令行無比強大。

            posted @ 2011-10-30 12:00 Climber.pI 閱讀(2397) | 評論 (0)編輯 收藏

            初賽散記

            回家的一天多, 狀態很頹, "勤能補拙是良訓, 一分辛苦一分才", 我還是太懶了.
            試室里熟人很多, 見了好多人, 和夏侯同桌. 題目很水, 于是被坑了, 相較于最近五年的真題, 完善程序的難度再創新低, 問題解決也水的可以, 于是分數下水漲船高, 加之名額減少. 形勢急矣.
            幾乎是考出經驗了, 所有準備非常充分的筆試, 大都會出現一些不由自主的看錯, 解決的方式不外乎多看幾遍. NOIp初賽的區分度主要來自完善和問題解決, 但是這兩部分今年都成了水題, 閱讀分值大, 丟不起.
            反正肯定過了, 怨天尤人毫無意義.

            可以反映出一些訓練中存在的問題:
            1. 如何查錯 -> 反復
            2. 寫的大多是寫過的陳題, 很少寫新題
            3. 太依賴第一印象 -> 批判性思維

            這次初賽全卷初步寫完還有幾乎1h的時間, 但是接下來的1h卻沒有得到任何分數, 雖然查到了10分左右的錯誤但是并未改對. 越是簡單題越要反復讀題, 做的慢反而不會出問題. 如果定義一個概念叫做有效時間的話. 去年初賽的有效時間就是開場的幾十分鐘和最后的幾十分鐘, 今年初賽的有效時間就是第一小時, 去年復賽的有效時間只有1h, 前年復賽的有效時間是1.5h. 如何讓剩下的時間變成有效時間, 亟待解決.
            仔細想想, 我習慣開場先通讀題目做出大致判斷, 但是沒有考慮第一反應錯了會怎么辦, 也就是說對大方向的質疑很少. 昨天第三題和第四題很可能都是由于第一印象導致分析出現偏差, 尤其是第四題, 開場認為大方向是圖論, 于是孤立看待矩陣中的每個點, 認為第四題的矩陣是類似鄰接表的東西, 一直朝這個方向想. 只要和題意南轅北轍, 剩下的就是浪費時間. 最后五分鐘想到了正確思路, 枚舉k=1,2,3..的答案, 然后找遞推式, 這是正確思路之一. 亦可以直接觀察. 于是知道的越多反而更容易理解錯, 除非很熟練, 自行車理論進一步得到證實啊.

            對于復賽也是一樣的問題, 新賽制模擬賽暴露的主要問題也是寫完程序后, 無法確定正確性. 我需要的不是計劃, 而是切實可行的步驟. 初賽和復賽沒什么關系, 歷史已經證明了這點. 我需要coding, 每周30h, 充實的時候往往沒有太多記憶, 記憶源于彷徨和不安. 
            可以考慮每天寫計劃, 然后寫總結, 時間不在多.
            ---------------------------------------------------------------------------
            對于分數線的估計, 提高全場最高wx93, 普及最高87.5, 提高60+ 20余人, 普及60+ 15人. 按照往年形勢估計, 分數線可能在60左右, 如果省里認為區分度有問題的話不排除降分的可能. lsm還是有可能過線的. 接了fsm的電話以后感覺好多了. 晚上和qj以及gXX神牛聊了一下天, 問了一些備考的問題和別的事情. 沒有時間頹廢, 即使是金中這樣的學校, 仍然有和大部分人方向不一致, 何況高級. 零散的時間可以用來寫水題和思考算法, 大塊時間不能浪費, 還是要用來寫模擬賽. 邊緣內容很多, 比如線段樹, 比如費用流.

            于是這周空白的作業怎么辦?

            posted @ 2011-10-15 20:50 Climber.pI 閱讀(269) | 評論 (0)編輯 收藏

            僅列出標題
            共8頁: 1 2 3 4 5 6 7 8 
            色综合合久久天天综合绕视看| 狠狠干狠狠久久| 麻豆久久久9性大片| 人妻无码精品久久亚瑟影视 | 狠狠色丁香婷婷久久综合| 色8久久人人97超碰香蕉987| 久久精品嫩草影院| 久久久无码精品亚洲日韩京东传媒 | 久久人妻少妇嫩草AV蜜桃| 国产午夜精品理论片久久影视| 女同久久| 精品熟女少妇aⅴ免费久久| 色综合久久中文字幕无码| 国产精品99久久久久久董美香 | 国产免费福利体检区久久| 97精品依人久久久大香线蕉97| 亚洲国产精品久久| 久久精品国产亚洲精品2020| 日本精品久久久久久久久免费| 国内精品久久久久| 亚洲av日韩精品久久久久久a | 少妇精品久久久一区二区三区 | 色综合久久综合中文综合网| 久久一本综合| 国内精品久久久久久久亚洲| 久久99国产精品一区二区| 亚洲AV无码一区东京热久久| 久久午夜无码鲁丝片秋霞 | 青青国产成人久久91网| 亚洲va中文字幕无码久久| 久久婷婷五月综合色奶水99啪| 久久人人爽人人精品视频| 国产精品久久久天天影视香蕉| 久久国产精品一国产精品金尊| 久久久久国产精品嫩草影院| 热久久视久久精品18| 中文字幕无码久久人妻| 欧美精品丝袜久久久中文字幕| 久久久WWW免费人成精品| 色99久久久久高潮综合影院| 模特私拍国产精品久久|