zoukankan      html  css  js  c++  java
  • bzoj 1500 维修数列

    一道操作很多的splay的题目。

    还是和原来一样, 减少代码量, 在最左边和最右边都添加一个新的虚节点。

    每一个节点都维护 从左端点开始的最大连续子序列, 右端点开始的最大连续子序列, 可以不取, 即为0, 还要维护这段区间的最大值。

    每次Update的时候更新数据。

    每次翻转的时候, 要把这个点的 左端点开始的最大连续子序列, 右端点开始的最大连续子序列 先进行交换,因为这个会对答案产生影响, 所以对于翻转区间来说, 要更新第一个翻转区间, 再打lazy, 不能直接不更新, 打lazy。

    还有就是 bzoj 开数组很花费时间, 所以要写一个函数来回收已经被删除掉的点。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
      4 #define LL long long
      5 #define ULL unsigned LL
      6 #define fi first
      7 #define se second
      8 #define pb push_back
      9 #define lson l,m,rt<<1
     10 #define rson m+1,r,rt<<1|1
     11 #define max3(a,b,c) max(a,max(b,c))
     12 #define min3(a,b,c) min(a,min(b,c))
     13 typedef pair<int,int> pll;
     14 const int inf = 0x3f3f3f3f;
     15 const LL INF = 0x3f3f3f3f3f3f3f3f;
     16 const LL mod =  (int)1e9+7;
     17 const int N = 5e5 + 100;
     18 int sta[N];
     19 int c[N];
     20 int top = 0, root;
     21 struct Node{
     22     int son[2], pre;
     23     int sz, val;
     24     int lf, rt, maxx, sum, ma;
     25     int lz1, lz2;
     26     void init(int m){
     27         sum = maxx = val = m;
     28         lf = rt = ma = max(0, m);
     29         son[0] = son[1] = pre = 0;
     30         sz = 1;
     31         lz1 = lz2 = 0;
     32     }
     33 }tr[N];
     34 void GG(int x, int v){
     35     if(!x) return ;
     36     tr[x].lz2 = 1;
     37     tr[x].val = tr[x].maxx = v;
     38     tr[x].sum = tr[x].sz * v;
     39     tr[x].lf = tr[x].rt = tr[x].ma = max(0, tr[x].sum);
     40 }
     41 void Push_Up(int x){
     42     if(!x) return ;
     43     int &l = tr[x].son[0], &r = tr[x].son[1];
     44     tr[x].sz = 1 + tr[l].sz + tr[r].sz;
     45     tr[x].sum = tr[l].sum + tr[r].sum + tr[x].val;
     46     tr[x].maxx = max3(tr[x].val, tr[l].maxx, tr[r].maxx);
     47     tr[x].lf = max(tr[l].lf, tr[l].sum + tr[r].lf + tr[x].val);
     48     tr[x].rt = max(tr[r].rt, tr[r].sum + tr[l].rt + tr[x].val);
     49     tr[x].ma = max3(tr[l].ma, tr[r].ma, tr[l].rt + tr[r].lf + tr[x].val);
     50 }
     51 void Push_Down(int x){
     52     if(!x) return ;
     53     int &l = tr[x].son[0], &r = tr[x].son[1];
     54     if(tr[x].lz1){
     55         tr[x].lz1 = 0;
     56         swap(l, r);
     57         swap(tr[l].lf, tr[l].rt);
     58         swap(tr[r].lf, tr[r].rt);
     59         tr[l].lz1 ^= 1;
     60         tr[r].lz1 ^= 1;
     61     }
     62     if(tr[x].lz2){
     63         tr[x].lz2 = 0;
     64         GG(l, tr[x].val);
     65         GG(r, tr[x].val);
     66     }
     67 }
     68 int build(int ll, int rr){
     69     if(ll > rr) return 0;
     70     int x = sta[top--];
     71     tr[x].init(c[ll]);
     72     tr[x].son[1] = build(ll+1, rr);
     73     tr[tr[x].son[1]].pre = x;
     74     Push_Up(x);
     75     return x;
     76 }
     77 char s[50];
     78 
     79 void rotate(int x){
     80     int y = tr[x].pre;
     81     int z = tr[y].pre;
     82     int k = tr[y].son[1] == x;
     83     tr[x].pre = z;
     84     tr[z].son[y == tr[z].son[1]] = x;
     85     tr[y].son[k] = tr[x].son[k^1];
     86     tr[tr[x].son[k^1]].pre = y;
     87     tr[y].pre = x;
     88     tr[x].son[k^1] = y;
     89     Push_Up(y);
     90 }
     91 void Splay(int x, int goal){
     92     Push_Down(x);
     93     while(tr[x].pre != goal){
     94         int y = tr[x].pre;
     95         int z = tr[y].pre;
     96         if(z != goal){
     97             if((tr[y].son[0] == x) ^ (tr[z].son[0] ==  y)) rotate(x);
     98             else rotate(y);
     99         }
    100         rotate(x);
    101     }
    102     if(!goal) root = x;
    103     Push_Up(x);
    104 }
    105 int Find(int x, int p){
    106     Push_Down(p);
    107     int &l = tr[p].son[0], &r = tr[p].son[1];
    108     if(x == tr[l].sz + 1) return p;
    109     if(x <= tr[l].sz) return Find(x, l);
    110     return Find(x - tr[l].sz - 1, r);
    111 }
    112 void Insert(int l, int num){
    113     int tt = build(1, num);
    114     int pl = Find(l+1, root);
    115     int pr = Find(l+2, root);
    116     Splay(pr, 0);
    117     Splay(pl, pr);
    118     tr[pl].son[1] = tt;
    119     tr[tt].pre = pl;
    120     Push_Up(pl);
    121     Push_Up(pr);
    122 }
    123 void Clear(int x){
    124     if(tr[x].son[0]) Clear(tr[x].son[0]);
    125     if(tr[x].son[1]) Clear(tr[x].son[1]);
    126     sta[++top] = x;
    127 }
    128 void Delete(int l, int r){
    129     int pl = Find(l, root);
    130     int pr = Find(r+2, root);
    131     Splay(pl, 0);
    132     Splay(pr, pl);
    133     Clear(tr[pr].son[0]);
    134     tr[pr].son[0] = 0;
    135     Push_Up(pr);
    136     Push_Up(pl);
    137 }
    138 
    139 void Make_same(int l, int r, int v){
    140     int pl = Find(l, root);
    141     int pr = Find(r+2, root);
    142     Splay(pl, 0);
    143     Splay(pr, pl);
    144     GG(tr[pr].son[0], v);
    145     int t = tr[pr].son[0];
    146     Push_Up(pr);
    147     Push_Up(pl);
    148 }
    149 void Reverse(int l, int r){
    150     int pl = Find(l, root);
    151     int pr = Find(r+2, root);
    152     Splay(pl, 0);
    153     Splay(pr, pl);
    154     tr[tr[pr].son[0]].lz1 ^= 1;
    155     Push_Down(tr[pr].son[0]);
    156     Push_Up(tr[pr].son[0]);
    157     Push_Up(pr);
    158     Push_Up(pl);
    159 }
    160 int Get_sum(int l, int r){
    161     int pl = Find(l, root);
    162     int pr = Find(r+2, root);
    163     Splay(pl, 0);
    164     Splay(pr, pl);
    165     return tr[tr[pr].son[0]].sum;
    166 }
    167 int Max_sum(){
    168     if(tr[root].maxx < 0) return tr[root].maxx;
    169     return tr[root].ma;
    170 }
    171 int main(){
    172     for(int i = N-50; i > 0; i--) sta[++top] = i;
    173     int n, m;
    174     scanf("%d%d", &n, &m);
    175     for(int i = 1; i <= n; i++) scanf("%d", &c[i]);
    176     c[0] = c[n+1] = -inf;
    177     tr[0].maxx = tr[0].val = -inf;
    178     root = build(0, n+1);
    179     int l, r, t;
    180     while(m--){
    181         scanf("%s", s);
    182         if(s[0] == 'I'){
    183             scanf("%d%d", &l, &r);
    184             for(int i = 1; i <= r; i++) scanf("%d", &c[i]);
    185             Insert(l,r);
    186         }
    187         else if(s[0] == 'D'){
    188             scanf("%d%d", &l, &r);
    189             Delete(l, l+r-1);
    190         }
    191         else if(s[2] == 'K'){
    192             scanf("%d%d%d", &l, &r, &t);
    193             Make_same(l, l+r-1, t);
    194         }
    195         else if(s[0] == 'R'){
    196             scanf("%d%d", &l, &r);
    197             Reverse(l, l+r-1);
    198         }
    199         else if(s[0] == 'G'){
    200             scanf("%d%d", &l, &r);
    201             printf("%d
    ", Get_sum(l, l+r-1));
    202         }
    203         else {
    204             printf("%d
    ", Max_sum());
    205         }
    206     }
    207     return 0;
    208 }
    View Code
  • 相关阅读:
    k8s service的DNS名称解析之CoreDNS
    k8s service负载均衡实现之iptables
    k8s 将项目暴露到互联网访问
    k8s 日志按体现分类与采集思路
    k8s ingressd的http对外暴露网站
    k8s 容器交付流程和项目部署流程
    k8s ingress使用DaemonSet部署
    Google Base与科学家数据共享 (Nature Vol 438|24 November 2005)
    总结:rdf:ID和rdf:about的区别(转载)
    一个元搜索引擎
  • 原文地址:https://www.cnblogs.com/MingSD/p/9453231.html
Copyright © 2011-2022 走看看