zoukankan      html  css  js  c++  java
  • 【bzoj1552/3506】[Cerc2007]robotic sort splay翻转,区间最值

    【bzoj1552/3506】[Cerc2007]robotic sort

    Description

    Input

    输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。

    Output

    输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,(1 < = Pi < = N),Pi表示第i次操作前第i小的物品所在的位置。 注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。

    Sample Input

    6
    3 4 5 1 6 2

    Sample Output

    4 6 4 5 6 6
     
    题解:裸题
      1 #include<cstring>
      2 #include<cmath>
      3 #include<algorithm>
      4 #include<iostream>
      5 #include<cstdio>
      6 
      7 #define inf 1000000007
      8 #define N 100007
      9 #define ls c[p][0]
     10 #define rs c[p][1]
     11 using namespace std;
     12 inline int read()
     13 {
     14     int x=0,f=1;char ch=getchar();
     15     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
     16     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     17     return x*f;
     18 }
     19 
     20 int n,rt;
     21 int a[N],rev[N],mi[N],flag[N],fa[N],sz[N],c[N][2],val[N],s[N];
     22 
     23 void update(int p)
     24 {
     25     sz[p]=sz[ls]+sz[rs]+1;
     26     mi[p]=val[p],flag[p]=p;
     27     if ((mi[ls]<mi[p])||(mi[ls]==mi[p]&&flag[p]>flag[ls])) mi[p]=mi[ls],flag[p]=flag[ls];
     28     if ((mi[rs]<mi[p])||(mi[rs]==mi[p]&&flag[p]>flag[rs])) mi[p]=mi[rs],flag[p]=flag[rs];
     29 }
     30 void pushdown(int p)
     31 {
     32     if (rev[p])
     33     {
     34         rev[p]^=1,rev[ls]^=1,rev[rs]^=1;
     35         swap(c[p][0],c[p][1]);
     36     }
     37 }
     38 void build(int l,int r,int f)
     39 {
     40     if (l>r) return;
     41     if (l==r)
     42     {
     43         val[l]=a[l],sz[l]=1,fa[l]=f,mi[l]=a[l],flag[l]=l;
     44         if (l<f) c[f][0]=l;
     45         else c[f][1]=l;
     46         return;
     47     }
     48     int mid=(l+r)>>1;
     49     build(l,mid-1,mid),build(mid+1,r,mid);
     50     if (mid<f) c[f][0]=mid;
     51     else c[f][1]=mid;
     52     fa[mid]=f,val[mid]=a[mid],mi[mid]=a[mid],flag[mid]=mid;
     53     update(mid);
     54 }
     55 void rotate(int x,int &k)
     56 {
     57     int y=fa[x],z=fa[y],l,r;
     58     if (c[y][0]==x) l=0;else l=1;r=l^1;
     59     if (y==k) k=x;//交换后x就等于y 
     60     else if (c[z][0]==y) c[z][0]=x;
     61     else c[z][1]=x;
     62     fa[x]=z,fa[y]=x,fa[c[x][r]]=y;
     63     c[y][l]=c[x][r],c[x][r]=y;
     64     update(y),update(x);
     65 }
     66 void splay(int x,int &k)
     67 {
     68     int top=0;s[++top]=x;
     69     for(int i=x;fa[i];i=fa[i])
     70         s[++top]=fa[i];
     71     for(int i=top;i;i--)
     72         if(rev[s[i]])pushdown(s[i]);
     73     while(x!=k)
     74     {
     75         int y=fa[x],z=fa[y];
     76         if (y!=k)
     77         {
     78             if (c[y][0]==x^c[z][0]==y) rotate(x,k);
     79             else rotate(y,k);
     80         }
     81         rotate(x,k);
     82     }
     83 }
     84 int find(int p,int num)
     85 {
     86     pushdown(p);
     87     if (sz[ls]>=num) return find(ls,num);
     88     else if (sz[ls]+1==num) return p;
     89     else return find(rs,num-sz[ls]-1); 
     90 }
     91 int query(int l,int r)
     92 {
     93     int x=find(rt,l),y=find(rt,r+2);
     94     splay(x,rt),splay(y,c[x][1]);
     95     int now=c[y][0];
     96     return flag[now];
     97 }
     98 void spin(int l,int r)
     99 {
    100     int x=find(rt,l),y=find(rt,r+2);
    101     splay(x,rt),splay(y,c[x][1]);
    102     int now=c[c[x][1]][0];
    103     rev[now]^=1;
    104 }
    105 int main()
    106 {
    107     freopen("fzy.in","r",stdin);
    108     freopen("fzy.out","w",stdout);
    109     
    110     int n=read();
    111     for (int i=2;i<=n+1;i++)
    112         a[i]=read();
    113     a[1]=a[n+2]=a[0]=inf,mi[0]=inf;
    114     build(1,n+2,0),rt=(1+n+2)>>1;
    115     for (int i=1;i<=n;i++)
    116     {
    117         int wei=query(i,n);
    118         splay(wei,rt);
    119         if (i!=n) printf("%d ",sz[c[wei][0]]);
    120         else printf("%d",sz[c[wei][0]]);
    121         spin(i,sz[c[wei][0]]);
    122     }
    123 }
  • 相关阅读:
    CF1202F You Are Given Some Letters...
    CF1178E Archaeology
    PTA (Advanced Level) 1005 Spell It Right
    PTA (Advanced Level) 1004 Counting Leaves
    Qt5——从零开始的Hello World教程(Qt Creator)
    PTA (Advanced Level) 1003 Emergency
    PTA (Advanced Level) 1002 A+B for Polynomials
    HDU 1272 小希的迷宫
    FZU 2150 Fire Game
    HihoCoder
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8098083.html
Copyright © 2011-2022 走看看