zoukankan      html  css  js  c++  java
  • BZOJ 1500: [NOI2005]维修数列 (splay tree)

    1500: [NOI2005]维修数列

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 4229  Solved: 1283
    [Submit][Status]

    Description

    Input

    输入文件的第1行包含两个数N和M,N表示初始时数列中数的个数,M表示要进行的操作数目。第2行包含N个数字,描述初始时的数列。以下M行,每行一条命令,格式参见问题描述中的表格。

    Output

    对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。

    Sample Input

    9 8
    2 -6 3 5 1 -5 -3 6 3
    GET-SUM 5 4
    MAX-SUM
    INSERT 8 3 -5 7 2
    DELETE 12 1
    MAKE-SAME 3 3 2
    REVERSE 3 6
    GET-SUM 5 4
    MAX-SUM

    Sample Output

    -1
    10
    1
    10

    HINT

    Source

    [Submit][Status]


    HOME Back


      1 /* ***********************************************
      2 Author        :kuangbin
      3 Created Time  :2013/8/27 3:28:32
      4 File Name     :F:2013ACM练习专题学习splay_tree_2维修数列.cpp
      5 ************************************************ */
      6 
      7 #include <stdio.h>
      8 #include <string.h>
      9 #include <iostream>
     10 #include <algorithm>
     11 #include <vector>
     12 #include <queue>
     13 #include <set>
     14 #include <map>
     15 #include <string>
     16 #include <math.h>
     17 #include <stdlib.h>
     18 #include <time.h>
     19 using namespace std;
     20 
     21 #define Key_value ch[ch[root][1]][0]
     22 const int MAXN = 500010;
     23 const int INF = 0x3f3f3f3f;
     24 int pre[MAXN],ch[MAXN][2],key[MAXN],size[MAXN];
     25 int root,tot1;
     26 int sum[MAXN],rev[MAXN],same[MAXN];
     27 int lx[MAXN],rx[MAXN],mx[MAXN];
     28 int s[MAXN],tot2;//内存池和容量
     29 int a[MAXN];
     30 int n,q;
     31 
     32 //debug部分**********************************
     33 void Treavel(int x)
     34 {
     35     if(x)
     36     {
     37         Treavel(ch[x][0]);
     38         printf("结点:%2d: 左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d
    ",x,ch[x][0],ch[x][1],pre[x],size[x]);
     39         Treavel(ch[x][1]);
     40     }
     41 }
     42 
     43 
     44 void debug()
     45 {
     46     printf("root:%d
    ",root);
     47     Treavel(root);
     48 }
     49 //以上是debug部分**************************************
     50 
     51 
     52 void NewNode(int &r,int father,int k)
     53 {
     54     if(tot2) r = s[tot2--];//取的时候是tot2--,存的时候就是++tot2
     55     else r = ++tot1;
     56     pre[r] = father;
     57     ch[r][0] = ch[r][1] = 0;
     58     key[r] = k;
     59     sum[r] = k;
     60     rev[r] = same[r] = 0;
     61     lx[r] = rx[r] = mx[r] = k;
     62     size[r] = 1;
     63 }
     64 void Update_Rev(int r)
     65 {
     66     if(!r)return;
     67     swap(ch[r][0],ch[r][1]);
     68     swap(lx[r],rx[r]);
     69     rev[r] ^= 1;
     70 }
     71 void Update_Same(int r,int v)
     72 {
     73     if(!r)return;
     74     key[r] = v;
     75     sum[r] = v*size[r];
     76     lx[r] = rx[r] = mx[r] = max(v,v*size[r]);
     77     same[r] = 1;
     78 }
     79 void push_up(int r)
     80 {
     81     int lson = ch[r][0], rson = ch[r][1];
     82     size[r] = size[lson] + size[rson] + 1;
     83     sum[r] = sum[lson] + sum[rson] + key[r];
     84     lx[r] = max(lx[lson],sum[lson] + key[r] + max(0,lx[rson]));
     85     rx[r] = max(rx[rson],sum[rson] + key[r] + max(0,rx[lson]));
     86     mx[r] = max(0,rx[lson]) + key[r] + max(0,lx[rson]);
     87     mx[r] = max(mx[r],max(mx[lson],mx[rson]));
     88 }
     89 void push_down(int r)
     90 {
     91     if(same[r])
     92     {
     93         Update_Same(ch[r][0],key[r]);
     94         Update_Same(ch[r][1],key[r]);
     95         same[r] = 0;
     96     }
     97     if(rev[r])
     98     {
     99         Update_Rev(ch[r][0]);
    100         Update_Rev(ch[r][1]);
    101         rev[r] = 0;
    102     }
    103 }
    104 void Build(int &x,int l,int r,int father)
    105 {
    106     if(l > r)return;
    107     int mid = (l+r)/2;
    108     NewNode(x,father,a[mid]);
    109     Build(ch[x][0],l,mid-1,x);
    110     Build(ch[x][1],mid+1,r,x);
    111     push_up(x);
    112 }
    113 void Init()
    114 {
    115     root = tot1 = tot2 = 0;
    116     ch[root][0] = ch[root][1] = size[root] = pre[root] = 0;
    117     same[root] = rev[root] = sum[root] = key[root] = 0;
    118     lx[root] = rx[root] = mx[root] = -INF;
    119     NewNode(root,0,-1);
    120     NewNode(ch[root][1],root,-1);
    121     for(int i = 0;i < n;i++)
    122         scanf("%d",&a[i]);
    123     Build(Key_value,0,n-1,ch[root][1]);
    124     push_up(ch[root][1]);
    125     push_up(root);
    126 }
    127 //旋转,0为左旋,1为右旋
    128 void Rotate(int x,int kind)
    129 {
    130     int y = pre[x];
    131     push_down(y);
    132     push_down(x);
    133     ch[y][!kind] = ch[x][kind];
    134     pre[ch[x][kind]] = y;
    135     if(pre[y])
    136         ch[pre[y]][ch[pre[y]][1]==y] = x;
    137     pre[x] = pre[y];
    138     ch[x][kind] = y;
    139     pre[y] = x;
    140     push_up(y);
    141 }
    142 //Splay调整,将r结点调整到goal下面
    143 void Splay(int r,int goal)
    144 {
    145     push_down(r);
    146     while(pre[r] != goal)
    147     {
    148         if(pre[pre[r]] == goal)
    149         {
    150             push_down(pre[r]);
    151             push_down(r);
    152             Rotate(r,ch[pre[r]][0] == r);
    153         }
    154         else
    155         {
    156             push_down(pre[pre[r]]);
    157             push_down(pre[r]);
    158             push_down(r);
    159             int y = pre[r];
    160             int kind = ch[pre[y]][0]==y;
    161             if(ch[y][kind] == r)
    162             {
    163                 Rotate(r,!kind);
    164                 Rotate(r,kind);
    165             }
    166             else
    167             {
    168                 Rotate(y,kind);
    169                 Rotate(r,kind);
    170             }
    171         }
    172     }
    173     push_up(r);
    174     if(goal == 0) root = r;
    175 }
    176 int Get_kth(int r,int k)
    177 {
    178     push_down(r);
    179     int t = size[ch[r][0]] + 1;
    180     if(t == k)return r;
    181     if(t > k)return Get_kth(ch[r][0],k);
    182     else return Get_kth(ch[r][1],k-t);
    183 }
    184 
    185 //在第pos个数后面插入tot个数
    186 void Insert(int pos,int tot)
    187 {
    188     for(int i = 0;i < tot;i++)scanf("%d",&a[i]);
    189     Splay(Get_kth(root,pos+1),0);
    190     Splay(Get_kth(root,pos+2),root);
    191     Build(Key_value,0,tot-1,ch[root][1]);
    192     push_up(ch[root][1]);
    193     push_up(root);
    194 }
    195 
    196 //删除子树
    197 void erase(int r)
    198 {
    199     if(!r)return;
    200     s[++tot2] = r;
    201     erase(ch[r][0]);
    202     erase(ch[r][1]);
    203 }
    204 //从第pos个数开始连续删除tot个数
    205 void Delete(int pos,int tot)
    206 {
    207     Splay(Get_kth(root,pos),0);
    208     Splay(Get_kth(root,pos+tot+1),root);
    209     erase(Key_value);
    210     pre[Key_value] = 0;
    211     Key_value = 0;
    212     push_up(ch[root][1]);
    213     push_up(root);
    214 }
    215 //将从第pos个数开始的连续的tot个数修改为c
    216 void Make_Same(int pos,int tot,int c)
    217 {
    218     Splay(Get_kth(root,pos),0);
    219     Splay(Get_kth(root,pos+tot+1),root);
    220     Update_Same(Key_value,c);
    221     push_up(ch[root][1]);
    222     push_up(root);
    223 }
    224 
    225 //将第pos个数开始的连续tot个数进行反转
    226 void Reverse(int pos,int tot)
    227 {
    228     Splay(Get_kth(root,pos),0);
    229     Splay(Get_kth(root,pos+tot+1),root);
    230     Update_Rev(Key_value);
    231     push_up(ch[root][1]);
    232     push_up(root);
    233 }
    234 //得到第pos个数开始的tot个数的和
    235 int Get_Sum(int pos,int tot)
    236 {
    237     Splay(Get_kth(root,pos),0);
    238     Splay(Get_kth(root,pos+tot+1),root);
    239     return sum[Key_value];
    240 }
    241 //得到第pos个数开始的tot个数中最大的子段和
    242 int Get_MaxSum(int pos,int tot)
    243 {
    244     Splay(Get_kth(root,pos),0);
    245     Splay(Get_kth(root,pos+tot+1),root);
    246     return mx[Key_value];
    247 }
    248 
    249 void InOrder(int r)
    250 {
    251     if(!r)return;
    252     push_down(r);
    253     InOrder(ch[r][0]);
    254     printf("%d ",key[r]);
    255     InOrder(ch[r][1]);
    256 }
    257 
    258 
    259 
    260 int main()
    261 {
    262     //freopen("in.txt","r",stdin);
    263     //freopen("out.txt","w",stdout);
    264      while(scanf("%d%d",&n,&q) == 2)   
    265     {
    266         Init();
    267         char op[20];
    268         int x,y,z;
    269         while(q--)
    270         {
    271             scanf("%s",op);
    272             if(strcmp(op,"INSERT") == 0)
    273             {
    274                 scanf("%d%d",&x,&y);
    275                 Insert(x,y);
    276             }
    277             else if(strcmp(op,"DELETE") == 0)
    278             {
    279                 scanf("%d%d",&x,&y);
    280                 Delete(x,y);
    281             }
    282             else if(strcmp(op,"MAKE-SAME") == 0)
    283             {
    284                 scanf("%d%d%d",&x,&y,&z);
    285                 Make_Same(x,y,z);
    286             }
    287             else if(strcmp(op,"REVERSE") == 0)
    288             {
    289                 scanf("%d%d",&x,&y);
    290                 Reverse(x,y);
    291             }
    292             else if(strcmp(op,"GET-SUM") == 0)
    293             {
    294                 scanf("%d%d",&x,&y);
    295                 printf("%d
    ",Get_Sum(x,y));
    296             }
    297             else if(strcmp(op,"MAX-SUM") == 0)
    298                 printf("%d
    ",Get_MaxSum(1,size[root]-2));
    299         }
    300     }
    301     return 0;
    302 }
  • 相关阅读:
    RJ-45与RJ-48的区别
    PCB设计铜铂厚度、线宽和电流关系
    PCB设计铜铂厚度、线宽和电流关系
    WiFi天线对PCB布局布线和结构的要求详解
    WiFi模块选型参考
    掩码是什么意思?
    计算机音频基础-PCM简介
    使用CSS2对页面中的文字添加彩色边框
    SQL Plus
    A Famous Music Composer
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3287822.html
Copyright © 2011-2022 走看看