zoukankan      html  css  js  c++  java
  • BZOJ1552/3506 [Cerc2007]robotic sort

    Splay

    与之前不同的是如果你仅仅是翻转左右区间的话可以在find里面做因为对他有影响的子树在做之前一定在他的上面从上到下搜索的过程可以把rever做了。

    但这道题要求我们输出转换之前的,因此不能保证之前的rev标记都已执行完因此就要从上到下做一遍。

    By:大奕哥

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int N=1e5+10;
      4 int fa[N],c[N][2],pos[N],rev[N],mn[N],w[N],size[N],n,m,rt;
      5 struct node
      6 {
      7     int pos,v;
      8     bool operator<(const node &b)const {
      9         if(v==b.v)return pos<b.pos;
     10         return v<b.v;
     11     }
     12 }a[N];
     13 void pushdown(int x)
     14 {
     15     if(rev[x])rev[c[x][0]]^=1,rev[c[x][1]]^=1,rev[x]^=1,swap(c[x][0],c[x][1]);
     16     mn[x]=w[x];pos[x]=x;
     17     if(mn[c[x][0]]<mn[x])mn[x]=mn[c[x][0]],pos[x]=pos[c[x][0]];
     18     if(mn[c[x][1]]<mn[x])mn[x]=mn[c[x][1]],pos[x]=pos[c[x][1]];
     19     size[x]=size[c[x][0]]+size[c[x][1]]+1;
     20 }
     21 void rotate(int x,int &k)
     22 {
     23     int y=fa[x],z=fa[y];
     24     int l=(c[y][1]==x);int r=l^1;
     25     if(y==k)k=x;else c[z][c[z][1]==y]=x;
     26     fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
     27     c[y][l]=c[x][r];c[x][r]=y;
     28     pushdown(y);pushdown(x);
     29 }
     30 int s[N],top;
     31 void splay(int x,int &k)
     32 {
     33     top=0;
     34     for(int i=x;i;i=fa[i])s[++top]=i;
     35     for(int i=top;i;--i)pushdown(s[i]);
     36     while(x!=k)
     37     {
     38         int y=fa[x],z=fa[y];
     39         if(y!=k)
     40         {
     41             if(x==c[y][0]^y==c[z][0])rotate(x,k);
     42             else rotate(y,k);
     43         }
     44         rotate(x,k);
     45     }
     46 }
     47 int find(int x,int k)
     48 {
     49     if(!x)return 0;pushdown(x);
     50     if(size[c[x][0]]+1==k)return x;
     51     else if(size[c[x][0]]+1>k)return find(c[x][0],k);
     52     else return find(c[x][1],k-size[c[x][0]]-1);
     53 }
     54 int query(int l,int r)
     55 {
     56     int x=find(rt,l),y=find(rt,r+2);
     57     splay(x,rt);splay(y,c[x][1]);
     58     return pos[c[y][0]];
     59 }
     60 void rever(int l,int r)
     61 {
     62     int x=find(rt,l),y=find(rt,r+2);
     63     splay(x,rt);splay(y,c[x][1]);
     64     int z=c[y][0];
     65     rev[z]^=1;
     66     return;
     67 }
     68 void build(int l,int r,int f){
     69     if(l>r)return;
     70     int mid=l+r>>1;
     71     fa[mid]=f;c[f][mid>=f]=mid;
     72     w[mid]=mn[mid]=a[mid].v;
     73     if(l==r)
     74     {
     75         rev[mid]=0;size[mid]=1;pushdown(mid);return;
     76     }
     77     build(l,mid-1,mid);build(mid+1,r,mid);
     78     pushdown(mid);
     79     return;
     80 }
     81 bool cmp(node aa,node bb){
     82     return aa.pos<bb.pos;
     83 }
     84 int ans[N];
     85 int main()
     86 {
     87     scanf("%d",&n);
     88     build(1,n+2,0);rt=(n+3)>>1;mn[0]=a[1].v=a[n+2].v=1e9;
     89     for(int i=2;i<=n+1;++i)scanf("%d",&a[i].v);
     90     for(int i=1;i<=n;++i)a[i+1].pos=i;
     91     sort(a+2,a+n+2);
     92     for(int i=1;i<=n;++i)a[i+1].v=i;
     93     sort(a+2,a+n+2,cmp);
     94     build(1,n+2,0);
     95     rt=(n+3)>>1;
     96     for(int i=1;i<=n;++i)
     97     {
     98         int x=query(i,n);
     99         splay(x,rt);
    100         ans[i]=size[c[x][0]];
    101         rever(i,ans[i]);
    102     }
    103     for(int i=1;i<n;++i)
    104     {
    105         printf("%d ",ans[i]);
    106     }
    107     printf("%d",ans[n]);
    108     return 0;
    109 }

    这个是标准的按照序列中的位置建树,每次splay之前要query一下。跑了3000ms,后来又在网上找了一种写法,直接按照权值建图,查找就直接splay对应的标号即可,2000ms。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int N=1e5+10;
      4 int fa[N],c[N][2],pos[N],rev[N],mn[N],w[N],size[N],n,m,rt;
      5 struct node
      6 {
      7     int pos,v;
      8     bool operator<(const node &b)const {
      9         if(v==b.v)return pos<b.pos;
     10         return v<b.v;
     11     }
     12 }a[N];
     13 bool cmp(node aa,node bb){
     14     return aa.pos<bb.pos;
     15 }
     16 void pushdown(int x)
     17 {
     18     if(rev[x])rev[c[x][0]]^=1,rev[c[x][1]]^=1,rev[x]^=1,swap(c[x][0],c[x][1]);
     19     mn[x]=w[x];pos[x]=x;
     20     if(mn[c[x][0]]<mn[x])mn[x]=mn[c[x][0]],pos[x]=pos[c[x][0]];
     21     if(mn[c[x][1]]<mn[x])mn[x]=mn[c[x][1]],pos[x]=pos[c[x][1]];
     22     size[x]=size[c[x][0]]+size[c[x][1]]+1;
     23 }
     24 void rotate(int x,int &k)
     25 {
     26     int y=fa[x],z=fa[y];
     27     int l=(c[y][1]==x);int r=l^1;
     28     if(y==k)k=x;else c[z][c[z][1]==y]=x;
     29     fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
     30     c[y][l]=c[x][r];c[x][r]=y;
     31     pushdown(y);pushdown(x);
     32 }
     33 int s[N],top;
     34 void splay(int x,int &k)
     35 {
     36     top=0;
     37     for(int i=x;i;i=fa[i])s[++top]=i;
     38     for(int i=top;i;--i)pushdown(s[i]);
     39     while(x!=k)
     40     {
     41         int y=fa[x],z=fa[y];
     42         if(y!=k)
     43         {
     44             if(x==c[y][0]^y==c[z][0])rotate(x,k);
     45             else rotate(y,k);
     46         }
     47         rotate(x,k);
     48     }
     49 }
     50 int find(int x,int k)
     51 {
     52     if(!x)return 0;pushdown(x);
     53     if(size[c[x][0]]+1==k)return x;
     54     else if(size[c[x][0]]+1>k)return find(c[x][0],k);
     55     else return find(c[x][1],k-size[c[x][0]]-1);
     56 }
     57 void rever(int l,int r)
     58 {
     59     int x=find(rt,l),y=find(rt,r+2);
     60     splay(x,rt);splay(y,c[x][1]);
     61     int z=c[y][0];
     62     rev[z]^=1;
     63     return;
     64 }
     65 void build(int l,int r,int f){
     66     if(l>r)return;
     67     int mid=l+r>>1;
     68     int now=a[mid].v,last=a[f].v;
     69     fa[now]=last;c[last][mid>=f]=now;
     70     if(l==r)
     71     {
     72         rev[now]=0;size[now]=1;return;
     73     }
     74     build(l,mid-1,mid);build(mid+1,r,mid);
     75     pushdown(now);
     76     return;
     77 }
     78 int ans[N];
     79 int main()
     80 {
     81     scanf("%d",&n);
     82     rt=(n+3)>>1;mn[0]=1e9;
     83     for(int i=2;i<=n+1;++i)scanf("%d",&a[i].v);
     84     for(int i=1;i<=n;++i)a[i+1].pos=i;
     85     sort(a+2,a+n+2);
     86     for(int i=2;i<=n+1;++i)a[i].v=i;a[1].v=1;a[n+2].v=n+2;
     87     sort(a+2,a+n+2,cmp);
     88     build(1,n+2,0);
     89     rt=a[(n+3)>>1].v;
     90     for(int i=1;i<=n;++i)
     91     {
     92         splay(i+1,rt);
     93         ans[i]=size[c[rt][0]];
     94         rever(i,ans[i]);
     95     }
     96     for(int i=1;i<n;++i)
     97     {
     98         printf("%d ",ans[i]);
     99     }
    100     printf("%d",ans[n]);
    101     return 0;
    102 }
  • 相关阅读:
    5.Docker服务进程关系
    朴素贝叶斯知识点概括
    k近邻法(KNN)知识点概括
    机器学习的应用实例
    HNU 10111 0-1矩阵
    CSU 1421 Necklace
    Poj 3469 Dual Core CPU
    Poj 2135 Farm Tour
    Poj 3180 The Cow Prom
    HDU 1004 Let the Balloon Rise
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8287925.html
Copyright © 2011-2022 走看看