• <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)  編輯 收藏 引用 所屬分類: 解題報告
            久久青青国产| 久久99精品国产麻豆宅宅| 日本高清无卡码一区二区久久| 99热精品久久只有精品| 无码精品久久一区二区三区 | 亚洲AV日韩精品久久久久| 中文字幕久久波多野结衣av| 国内精品久久人妻互换| 久久久久99精品成人片牛牛影视| 久久久久亚洲国产| 青青草原综合久久| 久久久久高潮综合影院| 草草久久久无码国产专区| 精品久久久久久无码不卡| 久久人妻少妇嫩草AV无码专区| 久久影院久久香蕉国产线看观看| 久久综合狠狠综合久久| 亚洲乱码日产精品a级毛片久久| 国产一级做a爰片久久毛片| 奇米影视7777久久精品人人爽| 日本精品久久久中文字幕| 亚洲国产欧美国产综合久久| 久久综合日本熟妇| 精品久久人人做人人爽综合| 国产91久久精品一区二区| 日产精品99久久久久久| 久久久久久精品免费看SSS| 久久久久无码中| 久久国产成人午夜AV影院| 99久久无码一区人妻a黑| 久久精品国产99久久久| 久久无码中文字幕东京热| 日韩AV毛片精品久久久| 日韩精品无码久久一区二区三| 久久人人爽人人爽AV片| 久久精品亚洲精品国产欧美| 久久午夜福利电影| 色狠狠久久综合网| 中文字幕久久精品无码| 久久发布国产伦子伦精品| 国内精品久久久人妻中文字幕|