• <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 西月弦 閱讀(1160) 評論(0)  編輯 收藏 引用 所屬分類: 解題報告
            欧美一级久久久久久久大片| 国产亚洲欧美精品久久久| 亚洲午夜精品久久久久久人妖| 久久国产精品无码HDAV| 欧美777精品久久久久网| 精品熟女少妇aⅴ免费久久| 久久亚洲日韩看片无码| 久久精品午夜一区二区福利| 国产一区二区精品久久凹凸| 狠狠色综合网站久久久久久久高清| 久久国产热精品波多野结衣AV| 久久精品国产亚洲Aⅴ香蕉| 久久免费的精品国产V∧| 久久精品成人免费国产片小草| 久久精品国产亚洲av麻豆色欲| 国产综合成人久久大片91| 久久亚洲精品人成综合网| 久久天天躁狠狠躁夜夜2020老熟妇| 久久久久久九九99精品| 久久婷婷五月综合97色直播| 国産精品久久久久久久| 久久久九九有精品国产| 久久九九久精品国产免费直播| 久久精品国产一区二区三区不卡 | 日韩av无码久久精品免费| AV无码久久久久不卡蜜桃| 久久精品国产99国产精品导航 | 久久狠狠爱亚洲综合影院| 久久久亚洲欧洲日产国码二区| 99久久精品国产高清一区二区 | 久久精品国产福利国产琪琪| 国产午夜精品久久久久九九电影| 久久久久亚洲av无码专区| 999久久久国产精品| 久久国产欧美日韩精品| 久久伊人五月天论坛| 超级碰久久免费公开视频| 国产欧美久久久精品| 久久99国产精一区二区三区| 国产精品视频久久久| 国产欧美一区二区久久|