转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526 by---cxlove
题目:给出4种操作
在某个位置,插入一个数
将某个位置的数删掉
将某个位置的数修改
查询某个区间的最大子段和
http://www.spoj.pl/problems/GSS6/
由于有添加和删除,线段树不好处理,其实是可以的,离线读入
Splay对于添加和删除比较方便吧
比较裸的Splay,哭瞎
从WA到TLE,WA的原因是初始化为0了,最大子段和可以是负的
TLE的一点优化貌似是写成结构体,底层优化
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<algorithm>
#define N 210005
#define inf 100000000
#define MOD 100000007
#define LL long long
#define Key_value ch[ch[root][1]][0]
#define _match(a,b) ((a)==(b))
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
int n,q,a[N];
struct Splay_tree{
int size[N],pre[N],val[N],ans[N],lx[N],rx[N],sum[N];
int ch[N][2],tot1,root,s[N],tot2;
//debug部分copy from hh
void Treaval(int x) {
if(x) {
Treaval(ch[x][0]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2c \n",x,ch[x][0],ch[x][1],pre[x],size[x],val[x]);
Treaval(ch[x][1]);
}
}
void debug() {printf("%d\n",root);Treaval(root);}
//以上Debug
inline void NewNode(int &r,int k,int father){
if(tot2) r=s[tot2--];
else r=++tot1;
ch[r][0]=ch[r][1]=0;
pre[r]=father;
size[r]=1;
val[r]=ans[r]=lx[r]=rx[r]=sum[r]=k;
}
inline void Push_Up(int x){
int l=ch[x][0],r=ch[x][1];
size[x]=size[l]+size[r]+1;
sum[x]=sum[l]+sum[r]+val[x];
lx[x]=max(lx[l],sum[l]+val[x]+max(lx[r],0));
rx[x]=max(rx[r],sum[r]+val[x]+max(rx[l],0));
ans[x]=max(max(ans[l],ans[r]),val[x]+max(lx[r],0)+max(rx[l],0));
}
inline void Bulid(int &r,int L,int R,int father){
if(L>R)
return ;
int mid=(L+R)/2;
NewNode(r,a[mid],father);
Bulid(ch[r][0],L,mid-1,r);
Bulid(ch[r][1],mid+1,R,r);
Push_Up(r);
}
inline void Init(){
tot1=tot2=root=0;
ch[root][0]=ch[root][1]=pre[root]=size[root]=sum[0]=0;
lx[root]=rx[root]=val[root]=ans[root]=-inf;
NewNode(root,-inf,0);
NewNode(ch[root][1],-inf,root);
Bulid(Key_value,1,n,ch[root][1]);
Push_Up(ch[root][1]);
Push_Up(root);
}
inline void Rotate(int x,int kind){
int y=pre[x];
ch[y][!kind]=ch[x][kind];
pre[ch[x][kind]]=y;
if(pre[y])
ch[pre[y]][ch[pre[y]][1]==y]=x;
pre[x]=pre[y];
ch[x][kind]=y;
pre[y]=x;
Push_Up(y);
}
inline void Splay(int r,int goal){
while(pre[r]!=goal){
if(pre[pre[r]]==goal)
Rotate(r,ch[pre[r]][0]==r);
else{
int y=pre[r];
int kind=(ch[pre[y]][0]==y);
if(ch[y][kind]==r){
Rotate(r,!kind);
Rotate(r,kind);
}
else{
Rotate(y,kind);
Rotate(r,kind);
}
}
}
Push_Up(r);
if(goal==0) root=r;
}
inline void RotateTo(int k, int goal) {
int x=root;
while(k!=size[ch[x][0]]+1){
if (k<=size[ch[x][0]]){
x=ch[x][0];
}else{
k-=(size[ch[x][0]]+1);
x=ch[x][1];
}
}
Splay(x,goal);
}
inline int Get_Kth(int r,int k){
int t=size[ch[r][0]]+1;
if(t==k) return r;
if(t>k) return Get_Kth(ch[r][0],k);
else return Get_Kth(ch[r][1],k-t);
}
inline void Insert(int pos,int size){
RotateTo(pos,0);
RotateTo(pos+1,root);
NewNode(Key_value,size,ch[root][1]);
Push_Up(ch[root][1]);
Push_Up(root);
}
inline void Delete(int pos){
RotateTo(pos,0);
RotateTo(pos+2,root);
Key_value=0;
Push_Up(ch[root][1]);
Push_Up(root);
}
inline void Replace(int pos,int m){
int x=Get_Kth(root,pos+1);
val[x]=m;
Splay(x,0);
}
inline int Query(int x,int y){
RotateTo(x,0);
RotateTo(y+2,root);
return ans[Key_value];
}
inline void InOrder(int r){
if(r==0)
return;
InOrder(ch[r][0]);
printf("%d\n",val[r]);
InOrder(ch[r][1]);
}
inline void Print(){
RotateTo(1,0);
RotateTo(n+2,root);
InOrder(Key_value);
}
}splay;
//外挂忽略
char CHAR() {
char res;
while (res = getchar(), !isalpha(res));
return res;
}
inline void scanf_(int &num){
char in;
bool neg=false;
while(((in=getchar()) > '9' || in<'0') && in!='-') ;
if(in=='-'){
neg=true;
while((in=getchar()) >'9' || in<'0');
}
num=in-'0';
while(in=getchar(),in>='0'&&in<='9')
num*=10,num+=in-'0';
if(neg)
num=0-num;
}
inline void printf_(int num){
bool flag=false;
if(num<0){
putchar('-');
num=-num;
}
int ans[10],top=0;
while(num!=0){
ans[top++]=num%10;
num/=10;
}
if(top==0)
putchar('0');
for(int i=top-1;i>=0;i--){
char ch=ans[i]+'0';
putchar(ch);
}
putchar('\n');
}
int main(){
while(scanf("%d",&n)!=EOF){
for(int i=1;i<=n;i++)
scanf_(a[i]);
splay.Init();
scanf_(q);
while(q--){
char ch=CHAR();
int pos,m;
if(ch=='I'){
n++;
scanf_(pos);scanf_(m);
splay.Insert(pos,m);
}
else if(ch=='D'){
n--;
scanf_(pos);
splay.Delete(pos);
}
else if(ch=='R'){
scanf_(pos);scanf_(m);
splay.Replace(pos,m);
}
else if(ch=='Q'){
scanf_(pos);scanf_(m);
printf_(splay.Query(pos,m));
}
}
}
return 0;
}