• bzoj 1251序列终结者 splay 区间翻转,最值,区间更新


    序列终结者

    Time Limit: 20 Sec  Memory Limit: 162 MB
    Submit: 4594  Solved: 1939
    [Submit][Status][Discuss]

    Description

    网上有许多题,就是给定一个序列,要你支持几种操作:A、B、C、D。一看另一道题,又是一个序列 要支持几种操作:D、C、B、A。尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量……这样 我也出一道题,我出这一道的目的是为了让大家以后做这种题目有一个“库”可以依靠,没有什么其他的意思。这道题目 就叫序列终结者吧。 【问题描述】 给定一个长度为N的序列,每个序列的元素是一个整数(废话)。要支持以下三种操作: 1. 将[L,R]这个区间内的所有数加上V。 2. 将[L,R]这个区间翻转,比如1 2 3 4变成4 3 2 1。 3. 求[L,R]这个区间中的最大值。 最开始所有元素都是0。

    Input

    第一行两个整数N,M。M为操作个数。 以下M行,每行最多四个整数,依次为K,L,R,V。K表示是第几种操作,如果不是第1种操作则K后面只有两个数。

    Output

    对于每个第3种操作,给出正确的回答。

    Sample Input

    4 4
    1 1 3 2
    1 2 4 -1
    2 1 3
    3 2 4

    Sample Output

    2
    【数据范围】
    N<=50000,M<=100000。
     
    题解:
      splay的一些操作都在了,区间翻转,区间求最值,区间加一个数。
      区间翻转需要注意一些,最值也是,写写就熟了。
      1 #include<cstring>
      2 #include<cmath>
      3 #include<algorithm>
      4 #include<iostream>
      5 #include<cstdio>
      6 
      7 #define inf 1000000007
      8 #define N 50007
      9 #define ls c[p][0]
     10 #define rs c[p][1]
     11 using namespace std;
     12 inline int read()
     13 {
     14     int x=0,f=1;char ch=getchar();
     15     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
     16     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     17     return x*f;
     18 }
     19 
     20 int n,m,rt;
     21 int fa[N],val[N],rev[N],mx[N],sz[N],flag[N],c[N][2];
     22 
     23 inline void update(int p)
     24 {
     25     sz[p]=sz[ls]+sz[rs]+1;
     26     mx[p]=max(mx[ls],mx[rs]);
     27     mx[p]=max(mx[p],val[p]);
     28 }
     29 inline void pushdown(int p)
     30 {
     31     if (flag[p])
     32     {
     33         int f=flag[p];flag[p]=0;
     34         if (ls){flag[ls]+=f,mx[ls]+=f,val[ls]+=f;}
     35         if (rs){flag[rs]+=f,mx[rs]+=f,val[rs]+=f;}
     36     }
     37     if (rev[p])
     38     {
     39         rev[p]^=1;
     40         rev[ls]^=1,rev[rs]^=1;
     41         swap(c[p][1],c[p][0]);
     42     }
     43 }
     44 void rotate(int x,int &k)
     45 {
     46     int y=fa[x],z=fa[y],l,r;
     47     if (c[y][0]==x) l=0;else l=1;r=l^1;
     48     if (y==k) k=x;//交换后x就等于y 
     49     else if (c[z][0]==y) c[z][0]=x;
     50     else c[z][1]=x;
     51     fa[x]=z,fa[y]=x,fa[c[x][r]]=y;
     52     c[y][l]=c[x][r],c[x][r]=y;
     53     update(y),update(x);
     54 }
     55 void splay(int x,int &k)
     56 {
     57     while(x!=k)
     58     {
     59         int y=fa[x],z=fa[y];
     60         if (y!=k)
     61         {
     62             if (c[y][0]==x^c[z][0]==y) rotate(x,k);
     63             else rotate(y,k);
     64         }
     65         rotate(x,k);
     66     }
     67 }
     68 int find(int p,int num)
     69 {
     70     pushdown(p);
     71     if (sz[ls]>=num) return find(ls,num);
     72     else if (sz[ls]+1==num) return p;
     73     else return find(rs,num-sz[ls]-1); 
     74 }
     75 void add(int l,int r,int z)
     76 {
     77     int x=find(rt,l),y=find(rt,r+2);
     78     splay(x,rt),splay(y,c[x][1]);
     79     int now=c[c[x][1]][0];
     80     val[now]+=z,flag[now]+=z,mx[now]+=z;
     81 }
     82 void spin(int l,int r)
     83 {
     84     int x=find(rt,l),y=find(rt,r+2);
     85     splay(x,rt),splay(y,c[x][1]);
     86     int now=c[c[x][1]][0];
     87     rev[now]^=1;
     88 }
     89 int query(int l,int r)
     90 {
     91     int x=find(rt,l),y=find(rt,r+2);
     92     splay(x,rt),splay(y,c[x][1]);
     93     int now=c[c[x][1]][0];
     94     return mx[now];
     95 }
     96 void build(int l,int r,int p)
     97 {
     98     if (l>r) return;
     99     if (l==r)
    100     {
    101         fa[l]=p,sz[l]=1;
    102         if (l<p) c[p][0]=l;
    103         else c[p][1]=l;
    104         return;
    105     }
    106     int mid=(l+r)>>1;
    107     build(l,mid-1,mid),build(mid+1,r,mid);
    108     fa[mid]=p;
    109     if (mid<p) c[p][0]=mid;
    110     else c[p][1]=mid;
    111     update(mid);
    112 }
    113 int main()
    114 {
    115     freopen("fzy.in","r",stdin);
    116     freopen("fzy.out","w",stdout);
    117     
    118     n=read(),m=read();mx[0]=-inf;
    119     build(1,n+2,0),rt=(n+3)>>1;
    120     while(m--)
    121     {
    122         int flag=read(),x,y,z;
    123         switch(flag)
    124         {
    125             case 1:x=read(),y=read(),z=read();add(x,y,z);break;
    126             case 2:x=read(),y=read();spin(x,y);break;
    127             case 3:x=read(),y=read();printf("%d
    ",query(x,y));break;
    128         }
    129     }
    130 }
  • 相关阅读:
    Python python __def__ Exception AttributeError: "'NoneType' object has no attribute
    Python sys.argv[]用法
    Python 编写通过DOS压缩的例子遇到的几个问题
    DOS rar压缩
    Oracle游标介绍
    C#保存日志文件到txt中,可追加保存,定时删除最后一次操作半年前日志文件
    VS2008生成解决方案卡顿、龟速
    VS工具箱中添加DevExpress控件
    CLR 无法从 COM 上下文 0x208f68 转换为 COM 上下文 0x2090d8,这种状态已持续 60 秒
    命名空间"xx"已经包含了"xx"的定义
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8097972.html
Copyright © 2020-2023  润新知