SPOJ GSS6 Can you answer these queries VI

Can you answer these queries VI

Time Limit: 2000ms
Memory Limit: 262144KB
This problem will be judged on  SPOJ. Original ID: GSS6
64-bit integer IO format: %lld      Java class name: Main

Given a sequence A of N (N <= 100000) integers, you have to apply Q (Q <= 100000) operations:

Insert, delete, replace an element, find the maximum contiguous(non empty) sum in a given interval.

Input

The first line of the input contains an integer N.
The following line contains N integers, representing the starting
sequence A1..AN, (|Ai| <= 10000).

The third line contains an integer Q. The next Q lines contains the operations in following form:

I x y: insert element y at position x (between x - 1 and x).
D x  : delete the element at position x.
R x y: replace element at position x with y.
Q x y: print max{Ai + Ai+1 + .. + Aj | x <= i <= j <= y}.

All given positions are valid, and given values are between -10000 and +10000.

The sequence will never be empty.

Output

For each "Q" operation, print an integer(one per line) as described above.

Example

Input:
5
3 -4 3 -1 6
10
I 6 2
Q 3 5
R 5 -4
Q 3 5
D 2
Q 1 5
I 2 -10
Q 1 6
R 2 -1
Q 1 6

Output:
8
3
6
3
5
 

Source

 
解题:splay
  1 #include <bits/stdc++.h>
  2 #define KT ch[ch[root][1]][0]
  3 using namespace std;
  4 const int INF = numeric_limits<int>::max();
  5 const int maxn = 210010;
  6 
  7 struct SplayTree {
  8     int fa[maxn],ch[maxn][2],sz[maxn],key[maxn];
  9     int lsum[maxn],rsum[maxn],ans[maxn],sum[maxn];
 10     int tot,root,seq[maxn];
 11     inline void pushup(int x) {
 12         if(!x) return;
 13         sz[x] = 1 + sz[ch[x][0]] + sz[ch[x][1]];
 14         sum[x] = key[x] + sum[ch[x][0]] + sum[ch[x][1]];
 15         lsum[x] = max(lsum[ch[x][0]],key[x] + sum[ch[x][0]] + max(0,lsum[ch[x][1]]));
 16         rsum[x] = max(rsum[ch[x][1]],key[x] + sum[ch[x][1]] + max(0,rsum[ch[x][0]]));
 17         ans[x] = max(max(ans[ch[x][0]],ans[ch[x][1]]),key[x] + max(0,rsum[ch[x][0]]) + max(0,lsum[ch[x][1]]));
 18     }
 19     void newnode(int &x,int val,int f) {
 20         x = ++tot;
 21         lsum[x] = rsum[x] = ans[x] = sum[x] = key[x] = val;
 22         fa[x] = f;
 23         ch[x][0] = ch[x][1] = 0;
 24         sz[x] = 1;
 25     }
 26     void build(int &x,int L,int R,int f) {
 27         if(L > R) return;
 28         int mid = (L + R)>>1;
 29         newnode(x,seq[mid],f);
 30         build(ch[x][0],L,mid-1,x);
 31         build(ch[x][1],mid+1,R,x);
 32         pushup(x);
 33     }
 34     void init(int n) {
 35         tot = root = 0;
 36         ch[0][0] = ch[0][1] = fa[0] = sum[0] = 0;
 37         lsum[0] = rsum[0] = ans[0] = key[0] = -INF;
 38         newnode(root,-INF,0);
 39         newnode(ch[root][1],-INF,root);
 40         build(KT,1,n,ch[root][1]);
 41         pushup(ch[root][1]);
 42         pushup(root);
 43     }
 44     void rotate(int x,int kd) {
 45         int y = fa[x];
 46         ch[y][kd^1] = ch[x][kd];
 47         fa[ch[x][kd]] = y;
 48         fa[x] = fa[y];
 49         ch[x][kd] = y;
 50         fa[y] = x;
 51         if(fa[x]) ch[fa[x]][y == ch[fa[x]][1]] = x;
 52         pushup(y);
 53     }
 54     void splay(int x,int goal = 0) {
 55         while(fa[x] != goal) {
 56             if(fa[fa[x]] == goal) rotate(x,x == ch[fa[x]][0]);
 57             else {
 58                 int y = fa[x],z = fa[y],s = (y == ch[z][0]);
 59                 if(x == ch[y][s]) {
 60                     rotate(x,s^1);
 61                     rotate(x,s);
 62                 } else {
 63                     rotate(y,s);
 64                     rotate(x,s);
 65                 }
 66             }
 67         }
 68         pushup(x);
 69         if(!goal) root = x;
 70     }
 71     int select(int k,int goal) {
 72         int x = root;
 73         while(sz[ch[x][0]] + 1 != k) {
 74             if(k < sz[ch[x][0]] + 1) x = ch[x][0];
 75             else {
 76                 k -= sz[ch[x][0]] + 1;
 77                 x = ch[x][1];
 78             }
 79         }
 80         splay(x,goal);
 81         return x;
 82     }
 83     void insert(int a,int b) {
 84         select(a - 1 + 1,0);
 85         select(a + 1,root);
 86         newnode(KT,b,ch[root][1]);
 87         pushup(ch[root][1]);
 88         pushup(root);
 89     }
 90     void remove(int a) {
 91         select(a - 1 + 1,0);
 92         select(a + 1 + 1,root);
 93         KT = 0;
 94         pushup(ch[root][1]);
 95         pushup(root);
 96     }
 97     void replace(int a,int b){
 98         int x = root;
 99         ++a;
100         while(sz[ch[x][0]] + 1 != a){
101             if(a < sz[ch[x][0]] + 1) x = ch[x][0];
102             else{
103                 a -= sz[ch[x][0]] + 1;
104                 x = ch[x][1];
105             }
106         }
107         key[x] = b;
108         splay(x,0);
109     }
110     int query(int a,int b){
111         select(a-1+1,0);
112         select(b+1+1,root);
113         return ans[KT];
114     }
115 } spt;
116 int main() {
117     int n,m,x,y;
118     char op[10];
119     while(~scanf("%d",&n)) {
120         for(int i = 1; i <= n; ++i)
121             scanf("%d",&spt.seq[i]);
122         spt.init(n);
123         scanf("%d",&m);
124         while(m--) {
125             scanf("%s",op);
126             if(op[0] == 'I') {
127                 scanf("%d%d",&x,&y);
128                 spt.insert(x,y);
129             } else if(op[0] == 'D') {
130                 scanf("%d",&x);
131                 spt.remove(x);
132             }else if(op[0] == 'R'){
133                 scanf("%d%d",&x,&y);
134                 spt.replace(x,y);
135             }else if(op[0] == 'Q'){
136                 scanf("%d%d",&x,&y);
137                 printf("%d\n",spt.query(x,y));
138             }
139         }
140     }
141     return 0;
142 }
View Code

 

转载于:https://www.cnblogs.com/crackpotisback/p/4891339.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值