zoukankan      html  css  js  c++  java
  • 牛客网多校第3场 C-shuffle card 【splay伸展树】

    题目链接:戳这里

    转自:戳这里

    关于splay入门:戳这里

    题意:给n个数,进行m次操作,每次都从n个数中取出连续的数放在最前面。

    解题思路:splay的区间操作。

    附代码:

     1 #include<iostream>
     2 #include<stdio.h>
     3 using namespace std;
     4 int n,m,sz,rt;
     5 int fa[100005],c[100005][2],id[100005];
     6 int size[100005];
     7 bool rev[100005];
     8 void pushup(int k)
     9 {
    10     int l=c[k][0],r=c[k][1];
    11     size[k]=size[l]+size[r]+1;
    12 }
    13 void pushdown(int k)
    14 {
    15     int l=c[k][0],r=c[k][1];
    16     if(rev[k])
    17     {
    18         swap(c[k][0],c[k][1]);
    19         rev[l]^=1;rev[r]^=1;
    20         rev[k]=0;
    21     }
    22 }
    23 void rotate(int x,int &k)
    24 {
    25     int y=fa[x],z=fa[y],l,r;
    26     if(c[y][0]==x)l=0;else l=1;r=l^1;
    27     if(y==k)k=x;
    28     else {if(c[z][0]==y)c[z][0]=x;else c[z][1]=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     pushup(y);pushup(x);
    32 }
    33 void splay(int x,int &k)
    34 {
    35     while(x!=k)
    36     {
    37         int y=fa[x],z=fa[y];
    38         if(y!=k)
    39         {
    40             if(c[y][0]==x^c[z][0]==y)rotate(x,k);
    41             else rotate(y,k);
    42         }
    43         rotate(x,k);
    44     }
    45 }
    46 int find(int k,int rank)
    47 {
    48     pushdown(k);
    49     int l=c[k][0],r=c[k][1];
    50     if(size[l]+1==rank)return k;
    51     else if(size[l]>=rank)return find(l,rank);
    52     else return find(r,rank-size[l]-1);
    53 }
    54 void rever(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     int z=c[y][0];
    59     rev[z]^=1;
    60 }
    61 void build(int l,int r,int f)
    62 {
    63     if(l>r)return;
    64     int now=id[l],last=id[f];
    65     if(l==r)
    66     {
    67         fa[now]=last;size[now]=1;
    68         if(l<f)c[last][0]=now;
    69         else c[last][1]=now;
    70         return;
    71     }
    72     int mid=(l+r)>>1;now=id[mid];
    73     build(l,mid-1,mid);build(mid+1,r,mid);
    74     fa[now]=last;pushup(mid);
    75     if(mid<f)c[last][0]=now;
    76     else c[last][1]=now;
    77 }
    78 int main()
    79 {
    80     scanf("%d%d",&n,&m);
    81     for(int i=1;i<=n+2;i++)
    82         id[i]=++sz;
    83     build(1,n+2,0);rt=(n+3)>>1;
    84     for(int i=1;i<=m;i++)
    85     {
    86         int l,r;
    87         scanf("%d%d",&l,&r);
    88         rever(1,l+r-1); //区间通过3次翻转,达到洗牌效果
    89         rever(1,r);
    90         rever(r+1,l+r-1);
    91     }
    92     for(int i=2;i<=n+1;i++)
    93         printf("%d ",find(rt,i)-1);
    94     return 0;
    95 }
    View Code
  • 相关阅读:
    53、Gif 控件GifView 的使用,播放gif图片
    52、图片缩放库 PhotoView
    51、自定义View基础和原理
    Adapter适配器 final int Id 导致选中的Item不在当前界面
    Linux目录结构
    Linux包管理工具分析
    Linux 软件包安装管理
    MySQL配置详解
    MySQL 5.5.x配置文件详解
    Linux Apache2 配置介绍
  • 原文地址:https://www.cnblogs.com/zmin/p/9402729.html
Copyright © 2011-2022 走看看