• COJ 0018 移动盒子


    20605移动盒子
    难度级别:B; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
    试题描述

    你有一行盒子,从左到右依次编号为1,2,3,……,n。可以执行一下四种指令:
        1、1 X Y表示将盒子 X 移动到盒子 Y 的左边。(如果X已经在Y的左边则忽略此指令)
        2、2 X Y表示把盒子X移动到盒子Y的右边。(如果X已经在Y的右边则忽略此指令)
        3、3 X Y表示交换盒子X和Y的位置。
        4、4表示反转整条链。
    输入指令保证合法,即X不等于Y。

    输入
    第一行包括两个正整数n和m,分别表示盒子个数和指令条数,接下来的m行,每行一条指令,如果是指令1、2或者3时,三部分间有一个空格分隔,如指令1 2 4表示将盒子2移动到盒子4的左边。
    输出
    一个正整数,表示所有奇数位置上盒子编号的数字之和。
    输入示例
    6 4
    1 1 4
    2 3 5
    3 1 6
    4
    输出示例
    12
    其他说明
    样例说明:当n=6时,在初始状态下执行1 1 4后,盒子序列为2 3 1 4 5 6,接下来执行2 3 5后,盒子序列变成2 1 4 5 3 6,再执行3 1 6,得到2 6 4 5 3 1,最终执行4,得到1 3 5 4 6 2。
    0 < n, m < 100001

    题解:赤裸裸的链表,可惜我没有写。我写的是splay tree你们怕不怕!!!

    写完真的是太爽了。。。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<queue>
      6 #include<cstring>
      7 #define PAU putchar(' ')
      8 #define ENT putchar('
    ')
      9 #define CH for(int d=0;d<=1;d++) if(ch[d])
     10 using namespace std;
     11 const int maxn=100000+10;
     12 struct node{
     13     node*fa,*ch[2];
     14     int c;bool rev;int siz;
     15     node(){c=-1;rev=false;siz=1;}
     16     void revt(){swap(ch[0],ch[1]);rev^=1;return;}
     17     void update(){siz=1;CH{siz+=ch[d]->siz;}return;}
     18     void down(){if(rev){CH{ch[d]->revt();}rev=false;}return;}
     19 }Splay[maxn],*root;int cnt=0;
     20 int parent(node*x,node*&y){return (y=x->fa)?y->ch[1]==x?1:y->ch[0]==x?0:-1:-1;}
     21 void rotate(node*x){
     22     node*y,*z;int d1=parent(x,y),d2=parent(y,z);
     23     if(y->ch[d1]=x->ch[d1^1]) y->ch[d1]->fa=y;
     24     y->fa=x;x->fa=z;x->ch[d1^1]=y;
     25     if(d2!=-1) z->ch[d2]=x;
     26     y->update();return;
     27 }
     28 void pushdown(node*x){
     29     static node*s[maxn];int top=0;
     30     for(node*y;;x=y){
     31         s[top++]=x;y=x->fa;
     32         if(!y||(y->ch[0]!=x&&y->ch[1]!=x)) break;
     33     } while(top--) s[top]->down();return;
     34 }
     35 node*splay(node*x){
     36     pushdown(x);node*y,*z;int d1,d2;
     37     while(true){
     38         if((d1=parent(x,y))<0) break;
     39         if((d2=parent(y,z))<0){rotate(x);break;}
     40         if(d1==d2) rotate(y),rotate(x);
     41         else rotate(x),rotate(x);
     42     } x->update();return x;
     43 }
     44 node*find(node*x,int rank){
     45     x->down();int kth=1;if(x->ch[0]) kth=x->ch[0]->siz+1;
     46     if(rank==kth) return x;
     47     if(rank<kth) return find(x->ch[0],rank);
     48     else return find(x->ch[1],rank-kth);
     49 }
     50 void split(node*&x,node*&y,int a){
     51     if(!a){y=x;x=NULL;return;}
     52     x=splay(find(x,a));y=x->ch[1];
     53     x->ch[1]=NULL;if(y)y->fa=NULL;x->update();return;
     54 }
     55 void split(node*&x,node*&y,node*&z,int a,int b){
     56     split(x,z,b);split(x,y,a-1);return;
     57 }
     58 void join(node*&x,node*y){
     59     if(!x){x=y;return;}if(!y)return;
     60     x=splay(find(x,x->siz));x->ch[1]=y;
     61     if(y)y->fa=x;x->update();return;
     62 }
     63 void join(node*&x,node*y,node*z){
     64     join(y,z);join(x,y);return;
     65 }
     66 int A[maxn],n,Q;
     67 void build(node*&x,int L,int R){
     68     if(L>R)return;int M=L+R>>1;
     69     x=&Splay[cnt++];x->c=A[M];
     70     build(x->ch[0],L,M-1);
     71     build(x->ch[1],M+1,R);
     72     if(x->ch[0]) x->ch[0]->fa=x;
     73     if(x->ch[1]) x->ch[1]->fa=x;
     74     x->update();return;
     75 }
     76 void reverse(int L,int R){
     77     node*x,*y;split(root,x,y,L,R);x->revt();join(root,x,y);return;
     78 }
     79 node*findll(node*x,int a){
     80     if(!x) return NULL;x->down();
     81     if(x->c==a) return x;
     82     node*t;
     83     if((t=findll(x->ch[0],a))||(t=findll(x->ch[1],a))) return t;
     84     return NULL;
     85 }
     86 void printer(node*x){
     87     if(!x){printf("NULL ");return;}
     88     x->down();
     89     if(x->ch[0])printer(x->ch[0]);
     90     printf("%d ",x->c);
     91     if(x->ch[1])printer(x->ch[1]);
     92     return;
     93 }
     94 int cz=1;long long sum=0;
     95 void counter(node*x){
     96     if(!x){return;}
     97     x->down();
     98     if(x->ch[0])counter(x->ch[0]);
     99     if((cz++)&1) sum+=x->c;
    100     if(x->ch[1])counter(x->ch[1]);
    101     return;
    102 }
    103 node*findfa(node*x){
    104     while(x->fa) x=x->fa;return x;
    105 }
    106 int findpos(int a){
    107     for(int i=1;i<=n;i++) if(A[i]==a) return i;
    108     return -1;
    109 }
    110 void split(node*&t1,node*&x,node*&t2,node*&y,node*&t3,int a,int b){
    111     splay(t1);
    112     x=findll(t1,a),y=findll(t1,b);
    113     splay(x);int kth1=1;if(x->ch[0]) kth1=x->ch[0]->siz+1;
    114     splay(y);int kth2=1;if(y->ch[0]) kth2=y->ch[0]->siz+1;
    115     if(kth1>kth2) swap(kth1,kth2);
    116     splay(t1);split(t1,x,t2,kth1,kth1);
    117     kth2-=kth1;split(t2,y,t3,kth2,kth2);return;
    118 }
    119 void join(node*&t1,node*x,node*t2,node*y,node*t3){
    120     join(t2,y,t3);join(t1,x,t2);return;
    121 }
    122 void swapnode(int a,int b){
    123     node*t1,*t2,*x,*y;
    124     split(root,x,t1,y,t2,a,b);
    125     join(root,y,t1,x,t2);return;
    126 }
    127 void shift(int a,int b,int tp){//1 right 0 left
    128     node*t1,*t2,*x,*y;
    129     split(root,x,t1,y,t2,a,b);
    130     y->ch[tp]=x;x->fa=y;y->update();
    131     join(root,NULL,t1,y,t2);return;
    132 }
    133 inline int read(){
    134     int x=0,sig=1;char ch=getchar();
    135     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
    136     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
    137     return x*=sig;
    138 }
    139 inline void write(int x){
    140     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    141     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    142     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    143 }
    144 inline void write(long long x){
    145     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    146     int len=0;long long buf[15];while(x)buf[len++]=x%10,x/=10;
    147     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    148 }
    149 void init(){
    150     n=read();Q=read();
    151     for(int i=1;i<=n;i++) A[i]=i;
    152     build(root,1,n);int tp,a,b;
    153     while(Q--){
    154         tp=read();
    155         if(tp==4) root->revt();
    156         else{
    157             a=read();b=read();
    158             if(tp==3) swapnode(a,b);
    159             else shift(a,b,tp-1);
    160         }
    161     }
    162     counter(root);
    163     write(sum);
    164     return;
    165 }
    166 void work(){
    167     return;
    168 }
    169 void print(){
    170     return;
    171 }
    172 int main(){init();work();print();return 0;}
  • 相关阅读:
    adb 常用命令及操作
    服务器被黑检查命令
    linux总结
    mysql数据库常用操作
    Python字符串所有操作函数
    Python提示信息表示内容
    Linux基础命令wget(如何联网下载?)
    Linux基础命令sz
    Linux基础命令rz
    Linux基础命令find
  • 原文地址:https://www.cnblogs.com/chxer/p/4554991.html
Copyright © 2020-2023  润新知