zoukankan      html  css  js  c++  java
  • [CQOI2014]排序机械臂

    题目大意:
      一个长度为$n(nleq10000)$的序列按照如下方式进行$n$次调整实现排序,每次在无序区域找出最小数的位置$p$,翻转区间$[i,j]$,此后区间$[1,i]$为有序。求每次操作$p$的值。

    思路:
      Splay维护区间。首先初始顺序为结点编号建立Splay,然后按照高度排序,求出每次操作的结点编号。每次询问时将询问点提到根,则$size[ch[root][0]]+1$即为所求的答案,翻转可以通过区间标记实现。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<climits>
     4 #include<algorithm>
     5 inline int getint() {
     6     register char ch;
     7     while(!isdigit(ch=getchar()));
     8     register int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int N=100003;
    13 int v[N],s[N];
    14 class SplayTree {
    15     private:
    16         int val[N],size[N],par[N],ch[N][2],root;
    17         bool rev[N];
    18         void push_down(const int &p) {
    19             if(!rev[p]) return;
    20             rev[ch[p][0]]^=1;
    21             rev[ch[p][1]]^=1;
    22             std::swap(ch[p][0],ch[p][1]);
    23             rev[p]=0;
    24         }
    25         void push_up(const int &p) {
    26             size[p]=size[ch[p][0]]+size[ch[p][1]]+1;
    27         }
    28         void rotate(const int &x) {
    29             const int y=par[x],z=par[y];
    30             push_down(y),push_down(x);
    31             const int b=x==ch[y][0];
    32             par[ch[x][b]=par[ch[y][!b]=ch[x][b]]=y]=x;
    33             par[ch[z][ch[z][1]==y]=x]=z;
    34             push_up(y),push_up(x);
    35         }
    36         void splay(int x,const int &goal) {
    37             for(register int y=par[x],z=par[y];y!=goal;rotate(x),z=par[y=par[x]]) {
    38                 if(z!=goal) rotate((x==ch[y][0])^(y==ch[z][0])?x:y);
    39             }
    40             if(!goal) root=x;
    41         }
    42         int find(int x) {
    43             for(register int y=root;;y=ch[y][size[ch[y][0]]+1<x]) {
    44                 push_down(y);
    45                 if(par[y]&&y==ch[par[y]][1]) x-=size[ch[par[y]][0]]+1;
    46                 if(size[ch[y][0]]+1==x) return y;
    47             }
    48         }
    49     public:
    50         void build(const int &n) {
    51             for(register int i=1;i<=n+2;i++) {
    52                 par[ch[i-1][1]=i]=i-1;
    53                 val[i]=v[i];
    54             }
    55             size[n+2]=1;
    56             splay(n+2,0);
    57         }
    58         int query(const int &x) {
    59             splay(s[x],0);
    60             const int ret=size[ch[s[x]][0]];
    61             splay(find(x-1),0);
    62             splay(find(ret+2),root);
    63             rev[ch[ch[root][1]][0]]^=1;
    64             return ret;
    65         }
    66 };
    67 SplayTree t;
    68 inline bool cmp(const int &a,const int &b) {
    69     return v[a]==v[b]?a<b:v[a]<v[b];
    70 }
    71 int main() {
    72     const int n=getint();
    73     for(register int i=2;i<=n+1;i++) {
    74         v[i]=getint();
    75         s[i]=i;
    76     }
    77     t.build(n);
    78     std::sort(&s[2],&s[n+1]+1,cmp);
    79     v[1]=INT_MIN;
    80     v[n+2]=INT_MAX;
    81     for(register int i=2;i<=n+1;i++) {
    82         printf("%d%c",t.query(i)," 
    "[i==n+1]);
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    c# 命令行下编译c#文件 // c# file类读写文件
    C#读取Xml
    System.IO.Path
    System.IO.Path 操作
    关于C#操作INI文件的总结
    C# 文件的一些基本操作(转)//用C#读写ini配置文件
    使用匿名类型做为ComboBox的DataSource
    C# Path 有关于文件路径等问题类(转)
    自考新教材--p60_5_2
    自考新教材--p60_5_1
  • 原文地址:https://www.cnblogs.com/skylee03/p/8516366.html
Copyright © 2011-2022 走看看