• <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>
            算法學社
            記錄難忘的征途
            posts - 141,comments - 220,trackbacks - 0

            題目描述:

               給一個長度為N(N<10,000)的數列,每次選取值最小的元素并翻轉前面的數列,然后刪除這個元素。請在每次操作之前輸出這個最小元素的位置。

            吐槽:

                1. 很好的splay熱身題,強勢推薦....
                2. 自底向上的維護對于懶惰標記的向下傳遞好像很無力? NO! 寫過zkw版線段樹么.... 看我之前寫過的一篇題解吧! 自底向上同樣可以傳遞懶惰標記。

            算法分析:

                這里的splay應用是... 放棄了元素之間的優先級,完全模擬一個數組(像笛卡爾樹那樣)
                要解決一些問題:
                    1. 如何查找元素最小的元素? 記錄最小值? NO! 數列的數組下標和splay的下標是一樣的!!!!
                    2. 如何翻轉一個區間? 先把這個區間“抽”出來,然后在這個區間的代表節點上加一個標記,傳遞標記的時候就旋轉左右子樹。
                    3. 如何刪除節點? 找到節點的前驅與后繼,然后通過splay前驅與后繼把這個節點“抽”出來。
                    4. 如何在向上splay的時候傳遞懶惰標記? 看我之前一篇題解吧! 在splay之前更新所有的父親節點!
                HDU代碼長度第三 ~~ 繼續figo的傳統
             1 #include<algorithm>
             2 #include<cstdio>
             3 #include<cassert>
             4 using namespace std;
             5 const int N = 100005;
             6 int n,splsize;
             7 struct node{
             8     int flag,sz,ch[2],p;
             9 } tree[N];
            10 struct sample{
            11     int id,v;
            12     bool operator < (sample A) const{
            13         return A.v == v ? id < A.id : v < A.v;
            14     }
            15 }num[N];
            16 // splay
            17 inline void upt(int x){
            18     tree[x].sz = tree[tree[x].ch[0]].sz + tree[tree[x].ch[1]].sz+1;
            19 }
            20 inline void setchd(int y,int x,int p){
            21     tree[y].ch[p] = x; tree[x].p = y;
            22 }
            23 void rot(int x){
            24     int y = tree[x].p;
            25     int chd = tree[y].ch[1] == x;
            26     setchd(tree[y].p,x,tree[tree[y].p].ch[1] == y);
            27     setchd(y,tree[x].ch[chd^1],chd);
            28     setchd(x,y,chd^1);
            29     upt(y);  upt(x);
            30 }
            31 void pushup(int x){
            32     if(tree[x].flag) {
            33         tree[x].flag=0;
            34         swap(tree[x].ch[0],tree[x].ch[1]);
            35         tree[tree[x].ch[0]].flag ^= 1;
            36         tree[tree[x].ch[1]].flag ^= 1;
            37     }
            38 }
            39 void dfs(int x){
            40     if(!x) return ;
            41     dfs(tree[x].p);
            42     pushup(x);
            43 }
            44 void splay(int x,int rt){
            45     dfs(x);
            46     while(tree[x].p!=rt){
            47         int y = tree[x].p;
            48         int flag = tree[y].ch[1] == x;
            49         if(tree[tree[x].p].p !=rt && flag == (tree[tree[y].p].ch[1] == y)) rot(y);
            50         rot(x);
            51     }
            52 }
            53 // function
            54 void ins(int x){
            55     setchd(x-1,x,1);
            56     tree[x].ch[0] = tree[x].ch[1] = tree[x].flag= 0;
            57     splay(x,0);
            58 }
            59 int cal(int x){
            60     splay(x,0);
            61     int ans = tree[tree[x].ch[0]].sz +1;
            62     tree[tree[x].ch[0]].flag ^=1;
            63     int u = tree[x].ch[0];
            64     int v = tree[x].ch[1];
            65     if(u==0) setchd(0,v,1);
            66     else if(v==0) setchd(0,u,1);
            67     else {
            68         pushup(u); pushup(v);
            69         while(tree[u].ch[1]){ u = tree[u].ch[1]; pushup(u);}
            70         while(tree[v].ch[0]){ v = tree[v].ch[0]; pushup(v);}
            71         splay(u,0);     splay(v,u); 
            72         assert(tree[v].ch[0] == x);
            73         tree[v].ch[0] = 0;
            74     }
            75     return ans;
            76 }
            77 // main
            78 int main(){
            79     tree[0].ch[0] = tree[0].ch[1] = tree[0].p = 0;
            80     while(~scanf("%d",&n) && n){
            81         for(int i=0; i<n; i++){
            82             scanf("%d",&num[i].v);
            83             ins(i+1);
            84             num[i].id = i;
            85         }
            86         sort(num,num+n);
            87         for(int i=0; i<n; i++){
            88             int pos = num[i].id + 1;
            89             int ans = cal(pos) + i;
            90             if(i) printf(" ");
            91             printf("%d",ans);
            92         }
            93         puts("");
            94     }
            95 }
            96 
            posted on 2012-05-10 20:54 西月弦 閱讀(1163) 評論(0)  編輯 收藏 引用 所屬分類: 解題報告
            亚洲国产成人精品久久久国产成人一区二区三区综 | 青青草原综合久久大伊人| 久久免费大片| 久久AV高潮AV无码AV| 久久久久亚洲AV无码网站| 国产国产成人精品久久| 久久久WWW成人| 色偷偷88888欧美精品久久久| 91精品国产高清久久久久久io | A级毛片无码久久精品免费| 香蕉久久夜色精品国产尤物| 久久久国产精品亚洲一区| 国产激情久久久久影院小草| 亚洲午夜久久久久久噜噜噜| 欧美成a人片免费看久久| 久久精品蜜芽亚洲国产AV| 伊色综合久久之综合久久| 久久综合丁香激情久久| 亚洲国产美女精品久久久久∴| 久久99精品久久久久久噜噜| 国产成人久久精品一区二区三区| 久久婷婷午色综合夜啪| 青青青青久久精品国产h久久精品五福影院1421 | 色综合久久中文字幕无码| 日韩电影久久久被窝网| 国产精品99久久久久久宅男| 九九久久自然熟的香蕉图片| 亚洲女久久久噜噜噜熟女| 欧美亚洲日本久久精品| 久久国产高清一区二区三区| 韩国无遮挡三级久久| 99久久99久久久精品齐齐| 性欧美大战久久久久久久久| 久久久久久久波多野结衣高潮| 亚洲国产精品综合久久网络 | 热99RE久久精品这里都是精品免费| 久久精品国产精品亜洲毛片| 久久99精品免费一区二区| 婷婷综合久久狠狠色99h| 伊人久久免费视频| 国产香蕉97碰碰久久人人|