• Tyvj 1729 文艺平衡树


    Description

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

    Input

    第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数
    接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n 

    Output

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

    Sample Input

    5 3

    1 3

    1 3

    1 4

    Sample Output

    4 3 2 1 5

    HINT

    N,M<=100000

    同样是非旋treap

    与splay做这道题的思路一样,交换左右子节点

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 using namespace std;
      6 struct Treap
      7 {
      8   Treap *l,*r;
      9   int val,size,lev;
     10   bool rev;
     11 }S[200001],*pos=S,*root;
     12 int n;
     13 typedef pair<Treap*,Treap*> Droot;
     14 void NewNode(Treap* &r,int val)
     15 {
     16   r=++pos;
     17   r->val=val;
     18   r->lev=rand();
     19   r->size=1;
     20   r->l=r->r=0;
     21 }
     22 int getsize(Treap* x)
     23 {
     24   if (!x) return 0;
     25   else return x->size;
     26 }
     27 void updata(Treap* x)
     28 {
     29   x->size=1;
     30   if (x->l) x->size+=x->l->size;
     31   if (x->r) x->size+=x->r->size;
     32 }
     33 Treap* rever(Treap* x)
     34 {
     35   if (!x) return 0;
     36   swap(x->l,x->r);
     37   x->rev^=1;
     38   return x;
     39 }
     40 void pushdown(Treap* x)
     41 {
     42   if (x->rev)
     43     {
     44       rever(x->l);
     45       rever(x->r);
     46       x->rev=0;
     47     }
     48 }
     49 Treap *merge(Treap *A,Treap *B)
     50 {
     51   if (!A) return B;
     52   if (!B) return A;
     53   if (A->lev<B->lev)
     54     {
     55       pushdown(A);
     56       A->r=merge(A->r,B);
     57       updata(A);
     58       return A;
     59     }
     60   else 
     61     {
     62       pushdown(B);
     63       B->l=merge(A,B->l);
     64       updata(B);
     65       return B;
     66     }
     67 }
     68 Droot split(Treap *x,int k)
     69 {
     70   if (!x) return Droot(0,0);
     71   Droot y;
     72   pushdown(x);
     73   if (getsize(x->l)>=k)
     74     {
     75       y=split(x->l,k);
     76       x->l=y.second;
     77       updata(x);
     78       y.second=x;
     79     }
     80   else 
     81     {
     82       y=split(x->r,k-getsize(x->l)-1);
     83       x->r=y.first;
     84       updata(x);
     85       y.first=x;
     86     }
     87   return y;
     88 }
     89 void reverse(int l,int r)
     90 {
     91   Droot x=split(root,l-1);
     92   Droot y=split(x.second,r-l+1);
     93   root=merge(merge(x.first,rever(y.first)),y.second);
     94 }
     95 int main()
     96 {int opt,x,q,i,l,r;
     97   cin>>n>>q;
     98   Treap* rt;
     99   for (i=1;i<=n;i++)
    100   NewNode(rt,i),root=merge(root,rt);
    101   while (q--)
    102     {
    103       scanf("%d%d",&l,&r);
    104       reverse(l,r);
    105     }
    106   for (i=1;i<=n;i++)
    107     {
    108       Droot y=split(root,1);
    109       printf("%d ",y.first->val);
    110       root=y.second;
    111     }
    112 }
  • 相关阅读:
    sql分页查询
    vi编辑器使用
    Linux命令:
    ubuntu中mysql忘记密码如何修改
    关于MySQL中自增的理解和设置
    MySQL中是索引
    MySQL中的分页操作结合python
    MySQL的分组和排序
    MySQL多表连接操作
    .NET Core App部署Linux
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7631541.html
Copyright © 2020-2023  润新知