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;
}
本文介绍了一道关于Treap数据结构的编程题及其解决方案。Treap是一种二叉搜索树和堆结合的数据结构,用于高效地处理插入、删除等操作。文章详细展示了Treap的实现代码,包括节点的创建、更新、合并、查询等功能,并通过具体实例说明了如何使用Treap解决连续区间至少包含一个数字的问题。
458

被折叠的 条评论
为什么被折叠?



