zoukankan      html  css  js  c++  java
  • 洛谷P3391 【模板】文艺平衡树(Splay)(FHQ Treap)

    题目背景

    这是一道经典的Splay模板题——文艺平衡树。

    题目描述

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

    输入输出格式

    输入格式:

    第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2, cdots n-1,n)(1,2,n1,n) m表示翻转操作次数

    接下来m行每行两个数 [l,r][l,r] 数据保证 1 leq l leq r leq n1lrn

    输出格式:

    输出一行n个数字,表示原始序列经过m次变换后的结果

    输入输出样例

    输入样例#1: 复制
    5 3
    1 3
    1 3
    1 4
    输出样例#1: 复制
    4 3 2 1 5

    说明

    n, m leq 100000n,m100000

     

    FHQ无敌,

    解决区间问题的时候按照$r$分成两个

    再按照$l$分成两个

    那么我们就得到了需要翻转的区间

    然后愉快的打标记就好啦

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<ctime>
      5 #include<cstdlib>
      6 using namespace std;
      7 #define ls T[now].ch[0]
      8 #define rs T[now].ch[1]
      9 const int MAXN=1e6+10;
     10 inline char nc()
     11 {
     12     static char buf[MAXN],*p1=buf,*p2=buf;
     13     return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
     14 }
     15 inline int read()
     16 {
     17     char c=nc();int x=0,f=1;
     18     while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}
     19     while(c>='0'&&c<='9'){x=x*10+c-'0',c=nc();}
     20     return x*f;
     21 }
     22 struct node
     23 {
     24     int ch[2],val,siz,pri,mark;
     25 }T[MAXN];
     26 int tot=0;
     27 int x,y,z,root=0,n,m;
     28 int newnode(int v)
     29 {
     30     T[++tot].siz=1;
     31     T[tot].val=v;
     32     T[tot].pri=rand();
     33     return tot;
     34 }
     35 void update(int now)
     36 {
     37     T[now].siz=T[ls].siz+T[rs].siz+1;
     38 }
     39 int Build(int l,int r)
     40 {
     41     if(l>r)    return 0;
     42     int mid=(l+r)>>1;
     43     int now=newnode(mid-1);
     44     ls=Build(l,mid-1);
     45     rs=Build(mid+1,r);
     46     update(now);
     47     return now;
     48 }
     49 void pushdown(int now)
     50 {
     51     if(T[now].mark&&now)
     52     {
     53         swap(ls,rs);
     54         if(ls)    T[ls].mark^=1;
     55         if(rs)    T[rs].mark^=1;
     56         T[now].mark=0;
     57     }
     58 }
     59 void split(int now,int k,int &x,int &y)
     60 {
     61     if(!now)    {x=y=0;return ;}
     62     pushdown(now);
     63     if(T[ls].siz<k)    
     64         x=now,split(rs,k-T[ls].siz-1,rs,y);
     65     else 
     66         y=now,split(ls,k,x,ls);
     67     update(now);
     68 }
     69 int merge(int x,int y)
     70 {
     71     if(!x||!y)    return x+y;
     72     pushdown(x);pushdown(y);
     73     if(T[x].pri<T[y].pri)    
     74     {
     75         T[x].ch[1]=merge(T[x].ch[1],y);
     76         update(x);
     77         return x;
     78     }
     79     else
     80     {
     81         T[y].ch[0]=merge(x,T[y].ch[0]);
     82         update(y);
     83         return y;
     84     }
     85 }
     86 void dfs(int now)
     87 {
     88     pushdown(now);
     89     if(T[now].ch[0]) dfs(T[now].ch[0]);
     90     if(T[now].val>=1&&T[now].val<=n)    printf("%d ",T[now].val);
     91     if(T[now].ch[1]) dfs(T[now].ch[1]);
     92 }
     93 int main()
     94 {
     95     #ifdef WIN32
     96     freopen("a.in","r",stdin);
     97     #else
     98     #endif
     99     //srand((unsigned)time(NULL));
    100     n=read(),m=read();
    101     root=Build(1,n+2);
    102     while(m--)
    103     {
    104         int l=read(),r=read();
    105         int a,b,c,d;
    106         split(root,r+1,a,b);
    107         split(a,l,c,d);
    108         T[d].mark^=1;
    109         root=merge( merge(c,d) ,b );
    110     }
    111     dfs(root);
    112     return 0;
    113 }
  • 相关阅读:
    条件判断和循环
    list 和tuple的使用
    python的五大数据类型
    简单的一个程序,猜字游戏
    redhat7 nfs的配置以及auto自动挂载
    nmcli添加网卡 并且修改设备名字 添加IP地址
    RHEL7 系统ISCSI存储环境搭建
    Java分布式锁
    24个Jvm面试题总结及答案
    最新天猫3轮面试题目:虚拟机+并发锁+Sql防注入+Zookeeper
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/8028506.html
Copyright © 2011-2022 走看看