zoukankan      html  css  js  c++  java
  • 1251. 序列终结者【平衡树-splay】

    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<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<map>
      5 #define MAXN (1000000+10)
      6 using namespace std;
      7 int Father[MAXN];
      8 int Son[MAXN][2];
      9 int Key[MAXN];
     10 int Size[MAXN];
     11 int Root,sz,n,m;
     12 int Max[MAXN],Val[MAXN],Add[MAXN],Rev[MAXN];
     13 using namespace std;
     14 
     15 inline int Get(int x)
     16 {
     17     return Son[Father[x]][1]==x;
     18 }
     19 
     20 inline void Update(int x)
     21 {
     22     Size[x]=Size[Son[x][0]]+Size[Son[x][1]]+1;
     23     Max[x]=max(Val[x],max(Max[Son[x][0]],Max[Son[x][1]]));
     24 }
     25 
     26 inline void Pushdown(int x)
     27 {
     28     if (Add[x])
     29     {
     30         if (Son[x][0])
     31         {
     32             Max[Son[x][0]]+=Add[x];
     33             Val[Son[x][0]]+=Add[x];
     34             Add[Son[x][0]]+=Add[x];
     35         }
     36         if (Son[x][1])
     37         {
     38             Max[Son[x][1]]+=Add[x];
     39             Val[Son[x][1]]+=Add[x];
     40             Add[Son[x][1]]+=Add[x];
     41         }
     42         Add[x]=0;
     43     }
     44     if (Rev[x])
     45     {
     46         Rev[x]=0;
     47         swap(Son[x][0],Son[x][1]);
     48         Rev[Son[x][0]]^=1;
     49         Rev[Son[x][1]]^=1;    
     50     }
     51 }
     52 
     53 inline void Rotate(int x)
     54 {
     55     Pushdown(Father[x]);
     56     Pushdown(x);
     57     int wh=Get(x);
     58     int fa=Father[x],fafa=Father[fa];
     59     Son[fa][wh]=Son[x][wh^1];
     60     Father[fa]=x;
     61     if (Son[fa][wh]) Father[Son[fa][wh]]=fa;
     62     Son[x][wh^1]=fa;
     63     Father[x]=fafa;
     64     if (fafa) Son[fafa][Son[fafa][1]==fa]=x;
     65     Update(fa);
     66     Update(x);
     67 }
     68 
     69 inline void Splay(int x,int tar)
     70 {
     71     for (int fa;(fa=Father[x])!=tar;Rotate(x))
     72         if (Father[fa]!=tar)
     73             Rotate(Get(fa)==Get(x)?fa:x);
     74     if (!tar) Root=x;
     75 }
     76 
     77 void Build(int l,int r,int fa)
     78 {
     79     if (l>r) return;
     80     if (l==r)
     81     {
     82         Size[l]=1;
     83         Father[l]=fa;
     84         Son[fa][l>fa]=l;
     85         return;
     86     }
     87     int mid=(l+r)>>1;
     88     Build(l,mid-1,mid);
     89     Build(mid+1,r,mid);
     90     Father[mid]=fa;
     91     Son[fa][mid>fa]=mid;
     92     Update(mid);
     93 }
     94 
     95 int Findx(int x)
     96 {
     97     int now=Root;
     98     while (1)
     99     {
    100         Pushdown(now);
    101         if (Size[Son[now][0]]>=x)
    102             now=Son[now][0];
    103         else
    104         {
    105             x-=Size[Son[now][0]];
    106             if (x==1)
    107             {
    108                 Splay(now,0);
    109                 return now;
    110             }
    111             x--;
    112             now=Son[now][1];
    113         }
    114     }
    115 }
    116 
    117 inline int Split(int x,int y)
    118 {
    119     int xx=Findx(x),yy=Findx(y);
    120     Splay(xx,0);
    121     Splay(yy,xx);
    122     return Son[yy][0];
    123 }
    124 
    125 int main()
    126 {
    127     int p,l,r,x;
    128     scanf("%d%d",&n,&m);
    129     Build(1,n+2,0);
    130     Root=(n+3)>>1;
    131     Max[0]=-0x7fffffff;
    132     for (int i=1;i<=m;++i)
    133     {
    134         scanf("%d",&p);
    135         if (p==1)
    136         {
    137             scanf("%d%d%d",&l,&r,&x);
    138             int node=Split(l,r+2);
    139             Val[node]+=x; 
    140             Max[node]+=x; 
    141             Add[node]+=x;
    142         }
    143         if (p==2)
    144         {
    145             scanf("%d%d",&l,&r);
    146             int node=Split(l,r+2);
    147             Rev[node]^=1;
    148         }
    149         if (p==3)
    150         {
    151             scanf("%d%d",&l,&r);
    152             int node=Split(l,r+2);
    153             printf("%d
    ",Max[node]);
    154         }
    155     }
    156 }
  • 相关阅读:
    搜索框
    鼠标hover时改变图片透明度和颜色(方法二)
    让背景带上颜色
    右侧固定导航栏
    react native环境配置
    左侧固定导航栏
    鼠标hover时改变图片透明度和颜色
    androidSDK配置环境变量
    cordova插件开发
    Python电子书分享
  • 原文地址:https://www.cnblogs.com/refun/p/8679181.html
Copyright © 2011-2022 走看看