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\n", Get_sum(l, l+r-1)); 202 } 203 else { 204 printf("%d\n", Max_sum()); 205 } 206 } 207 return 0; 208 }