spoj 4487 Can you answer these queries VI

treap模板题。注意连续区间至少要有一个数字,所以答案可能是负数


#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int INF=2e9+1;
inline int ran() { static int ranx = 654123789; return ranx += ranx<<2|1; }
struct Node {
        Node *ch[2];
        int val, maxv, sz, r, maxl, maxr, sum, nv;
}memo[401000],*nill,*root;
int tot;
int gcd(int a,int b) { return b==0 ? a : gcd(b,a%b); }
void up(Node *o) {
        if (o==nill) return ;
        o->sum = o->val+o->ch[0]->sum+o->ch[1]->sum;
        o->sz = o->ch[0]->sz + o->ch[1]->sz + 1;
        o->maxv = max(0,o->val);
        o->nv = o->val;
        o->maxl = max(o->ch[0]->maxl,o->ch[0]->sum+o->val+o->ch[1]->maxl);
        o->maxr = max(o->ch[1]->maxr,o->ch[1]->sum+o->val+o->ch[0]->maxr);
        o->maxv = max(o->maxv,max(o->maxl,o->maxr));
        o->maxv = max(o->maxv,o->ch[0]->maxr+o->val+o->ch[1]->maxl);
        o->maxv = max(o->maxv,max(o->ch[0]->maxv,o->ch[1]->maxv));
        if(o->ch[0]!=nill){
            o->nv = max(o->nv,o->ch[0]->nv);
        }
        if(o->ch[1]!=nill){
            o->nv = max(o->nv,o->ch[1]->nv);
        }
}
void New_node(Node *&o,int val=0) {
        o = &memo[tot++];
        o->ch[0] = o->ch[1] = nill;
        o->sz = 1;
        o->r = ran();
        o->val = val;
        up(o);
}
void cut(Node *o,Node *&a,Node *&b,int p) {
        if (o->sz <= p) a = o,b = nill;
        else if (p==0) a = nill,b = o;
        else {
                if (o->ch[0]->sz >= p) {
                        b = o;
                        cut(o->ch[0],a,b->ch[0],p);
                        up(b);
                } else {
                        a = o;
                        cut(o->ch[1],a->ch[1],b,p - o->ch[0]->sz - 1);
                        up(a);
                }
        }
}
void merge(Node *&o,Node *a,Node *b) {
        if (a==nill) o = b;
        else if (b==nill) o = a;
        else {
                if (a->r > b->r) {
                        o = a;
                        merge(o->ch[1],a->ch[1],b);
                        up(o);
                } else {
                        o = b;
                        merge(o->ch[0],a,b->ch[0]);
                        up(o);
                }
        }
}
void ins(int val,int p) {
        Node *a,*b,*c;
        cut(root,a,b,p);
        New_node(c,val);
        merge(a,a,c);
        merge(root,a,b);
}
void query(int l,int r) {
        Node *a,*b,*c;
        cut(root,a,b,l-1);
        cut(b,b,c,r-l+1);
        if(b->nv<=0)
            printf("%d\n",b->nv);
        else
            printf("%d\n",b->maxv);
        merge(b,b,c);
        merge(root,a,b);
}
void del(int p) {
        Node *a,*b,*c;
        cut(root,a,b,p-1);
        cut(b,b,c,1);
        merge(root,a,c);
}
void change(int p,int val) {
        Node *a,*b,*c;
        cut(root,a,b,p-1);
        cut(b,b,c,1);
        b->val = val;
        up(b);
        merge(b,b,c);
        merge(root,a,b);
}
int main() {
        int n, m, a, b, x, y;
        char s[33];
        while (~scanf("%d",&n)) {
                tot = 0;
                New_node(nill); nill->sz = 0, nill->sum=nill->maxl=nill->maxr=nill->maxv=0;
                root = nill;
                for (int i = 0; i < n; i ++) {
                        scanf("%d",&a);
                        ins(a,root->sz);
                }
                scanf("%d",&m);
                while (m--) {
                    scanf("%s",s);
                    if(s[0]=='I'){
                        scanf("%d%d",&x,&y);
                        ins(y,x-1);
                    }else if(s[0]=='D'){
                        scanf("%d",&x);
                        del(x);
                    }else if(s[0]=='R'){
                        scanf("%d%d",&x,&y);
                        change(x,y);
                    }else{
                        scanf("%d%d",&x,&y);
                        query(x,y);
                    }
                }
        }
        return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值