zoukankan      html  css  js  c++  java
  • hdu 1890 Robotic Sort splaytree+懒惰标记

    http://acm.hdu.edu.cn/showproblem.php?pid=1890

     给一个长度为N(N<10,000)的数列,每次选取值最小的元素并翻转前面的数列,然后删除这个元素。请在每次操作之前输出这个最小元素的位置。

    这里的splay应用是:放弃了元素之间的优先级,完全模拟一个数组(像笛卡尔树那样)
        要解决一些问题:
            1. 如何查找元素最小的元素? 记录最小值? NO! 数列的数组下标和splay的下标是一样的!!!!
            2. 如何翻转一个区间? 先把这个区间“抽”出来,然后在这个区间的代表节点上加一个标记,传递标记的时候就旋转左右子树。
            3. 如何删除节点? 找到节点的前驱与后继,然后通过splay前驱与后继把这个节点“抽”出来。
            4. 如何在向上splay的时候传递懒惰标记? 看我之前一篇题解吧! 在splay之前更新所有的父亲节点!
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 #define inf (1<<29)
     7 const int maxn = 100010;
     8 int n , splaysz;
     9 struct node {
    10     int p,chd[2],sz,flag;
    11     node (int P=0) {
    12         chd[0]=chd[1]=0;sz=0;
    13         p = P; flag = 0;
    14     }
    15 }tree[maxn];
    16 struct sample {
    17     int id , v;
    18     bool operator < (sample b) const {
    19         return v==b.v?id<b.id:v<b.v;
    20     }
    21 }num[maxn];
    22 inline void sc(int y,int x,int p) { tree[y].chd[p]=x;tree[x].p=y; }
    23 inline void update(int x) {
    24     tree[x].sz=tree[tree[x].chd[0]].sz+tree[tree[x].chd[1]].sz+1;
    25 }
    26 inline void rot(int x) {
    27     int y = tree[x].p;
    28     int w = tree[y].chd[1] == x;
    29     sc(tree[y].p,x,tree[tree[y].p].chd[1]==y);
    30     sc(y,tree[x].chd[w^1],w);
    31     sc(x,y,w^1);
    32     update(y);
    33     update(x);
    34 }
    35 void pushup(int x) {
    36     if(tree[x].flag) {
    37         tree[x].flag = 0;
    38         swap(tree[x].chd[0],tree[x].chd[1]);
    39         tree[tree[x].chd[0]].flag ^= 1;
    40         tree[tree[x].chd[1]].flag ^= 1;
    41     }
    42 }
    43 void dfs(int x) {
    44     if(!x) return;
    45     dfs(tree[x].p);
    46     pushup(x);
    47 }
    48 void splay(int x,int rt) {
    49     dfs(x);
    50     while(tree[x].p!=rt) {
    51         int y = tree[x].p;
    52         int w = tree[y].chd[1]==x;
    53         if(tree[y].p != rt && tree[tree[y].p].chd[w]==y) rot(y);
    54         rot(x);
    55     }
    56 }
    57 void insert(int x) {
    58     sc(x-1,x,1);
    59     tree[x].chd[0] = tree[x].chd[1] = tree[x].flag = 0;
    60     splay(x , 0);
    61 }
    62 int cal(int x) {
    63     splay(x , 0);
    64     int ans = tree[tree[x].chd[0]].sz + 1;
    65     tree[tree[x].chd[0]].flag ^= 1;
    66     int u = tree[x].chd[0];
    67     int v = tree[x].chd[1];
    68     if(u == 0) sc(0 , v , 1);
    69     else if(v == 0) sc(0 , u , 1);
    70     else {
    71         pushup(u); pushup(v);
    72         while(tree[u].chd[1]) { u=tree[u].chd[1];pushup(u); }
    73         while(tree[v].chd[0]) { v=tree[v].chd[0];pushup(v); }
    74         splay(u,0); splay(v,u);
    75         // assert(tree[v].chd[0] == x);
    76         tree[v].chd[0] = 0;
    77     }
    78     return ans;
    79 }
    80 int main() {
    81     tree[0] = node(0);
    82     while(~scanf("%d",&n) && n) {
    83         for(int i=0;i<n;i++) {
    84             scanf("%d",&num[i].v);
    85             insert(i+1);
    86             num[i].id = i;
    87         }
    88         sort(num,num+n);
    89         for(int i=0;i<n;i++) {
    90             int pos = num[i].id + 1;
    91             int ans = cal(pos) + i;
    92             if(i) putchar(' ');
    93             printf("%d",ans);
    94         }
    95         puts("");
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    静态链接到 MFC 的规则 DLL
    DLLAFX_MANAGE_STATE(AfxGetStaticModuleState())模块状态切换保护
    多线程专题之线程同步(1)
    UVa 4256 Salesmen dp
    nefu 661 Clockwise 水DP+略几何
    10635 Prince and Princess LCS&LIS
    UVa 3882 And Then There Was One 递推无力orz
    UVa 10192 Vacation 字符串dp
    UVa 11584 Partitioning by Palindromes 回文串dp
    UVa 10534 Wavio Sequence LIS
  • 原文地址:https://www.cnblogs.com/tobec/p/3252763.html
Copyright © 2011-2022 走看看