您的位置:首页 > 产品设计 > UI/UE

SPOJ 4487. Can you answer these queries VI(GSS6) splay

2014-03-04 23:29 531 查看
    一个序列,四中操作,在x前插入y;删除位置x的数;把位置x的数改成y;查询区间[x,y]的最大子段和。算是维护数列的简化版吧,但时间卡的要死=...输入挂+输出挂都用上了才勉强卡过去....

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
typedef int ll;
const int maxn=200000+10000;

int a[maxn];
int root,tot,n,m;
int p,q,tt,t,k,r;

inline int getint() {
int res;
char ch;
bool neg;
while (ch = getchar(), !isdigit(ch) && ch != '-')
;
if (ch == '-') {
res = 0;
neg = true;
} else {
res = ch - '0';
neg = false;
}
while (ch = getchar(), isdigit(ch))
res = res * 10 + ch - '0';
return neg ? -res : res;
}

inline char CHAR() {
char res;
while (res = getchar(), !isalpha(res))
;
return res;
}

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');
}

struct splaytree
{
ll key[maxn],sub[maxn],suff[maxn],pref[maxn],sum[maxn];
int pre[maxn],ch[maxn][2];
int stk[maxn];
int top;
int size[maxn];

inline void pushup(int r)
{
if (r==0) return;
size[r]=size[ch[r][0]]+1+size[ch[r][1]];
sum[r]=sum[ch[r][0]]+key[r]+sum[ch[r][1]];
pref[r]=max(pref[ch[r][0]],sum[ch[r][0]]+key[r]+max(0,pref[ch[r][1]]));
suff[r]=max(suff[ch[r][1]],sum[ch[r][1]]+key[r]+max(0,suff[ch[r][0]]));
sub[r]=max(0,suff[ch[r][0]])+key[r]+max(0,pref[ch[r][1]]);
sub[r]=max(sub[r],max(sub[ch[r][0]],sub[ch[r][1]]));
}

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;
pushup(y);
}
inline void splay(int x,int tgt)
{
while(pre[x]!=tgt)
{
int y=pre[x];

if (pre[pre[x]]==tgt)
{
rotate(x,ch[pre[x]][0]==x);
}
else
{
int kind=ch[pre[y]][0]==y;
if (ch[y][kind]==x)
{
rotate(x,kind^1);
rotate(x,kind);
}
else
{
rotate(y,kind);
rotate(x,kind);
}
}
}
pushup(x);
if (tgt==0) root=x;
}
inline int select(int k,int tgt)
{
int rt=root;
while(true)
{
if (k<=size[ch[rt][0]]) rt=ch[rt][0];
else if (k==size[ch[rt][0]]+1) break;
else k-=(size[ch[rt][0]]+1),rt=ch[rt][1];
}
if (tgt>=0) splay(rt,tgt);
return rt;

}
inline void newnode(int &r,int father,ll k)
{
// if (top)
// {
// r=stk[top--];
// }
// else r=++tot;
r=++tot;
pre[r]=father;
size[r]=1;
key[r]=k;
sum[r]=suff[r]=pref[r]=sub[r]=k;
ch[r][0]=ch[r][1]=0;
}
inline void build(int l,int r,int &x,int rt)
{
if (l>r) return;
int m=(l+r)>>1;
newnode(x,rt,a[m]);
build(l,m-1,ch[x][0],x);
build(m+1,r,ch[x][1],x);
pushup(x);
}
inline void init()
{
tot=root=0;
top=0;
newnode(root,0,-(1<<30));
newnode(ch[root][1],root,-(1<<30));
suff[0]=pref[0]=sub[0]=-(1<<30);
suff[1]=pref[1]=sub[1]=-(1<<30);
suff[2]=pref[2]=sub[2]=-(1<<30);

build(1,n,ch[ch[root][1]][0],ch[root][1]);
pushup(ch[root][1]);
pushup(root);
}

inline void insert(int posi,int num)
{
ll c;
select(posi+1,0);
select(posi+2,root);
int tp;
tp=getint();
newnode(ch[ch[root][1]][0],ch[root][1],tp);
pushup(ch[root][1]);
pushup(root);
}
inline void del(int posi)
{
select(posi,0);
select(posi+2,root);
int k=ch[ch[root][1]][0];
// recover(k);
pre[k]=0;
ch[ch[root][1]][0]=0;
pushup(ch[root][1]);
pushup(root);
}
inline void recover(int r)
{
if (!r) return;
stk[++top]=r;
recover(ch[r][0]);
recover(ch[r][1]);
}
inline int Max_sum(int l,int r)
{
select(l,0);
select(r+2,root);
return sub[ch[ch[root][1]][0]];
}
inline void modify(int posi,int x)
{
select(posi+1,0);
key[root]=x;
pushup(root);

}
}spt;
char cmd[30];
int x,y,z;
ll c;
int main()
{
//freopen("in.txt","r",stdin);
n=getint();
for (int i=1; i<=n; i++)
{
a[i]=getint();
}
spt.init();
m=getint();
char cc;
for (int i=1; i<=m; i++)
{
// cout<<ch[0][0]<<"---"<<ch[0][1]<<"--"<<pre[0]<<"hit----\n";
cc=CHAR();
if (cc=='I')
{
x=getint();
spt.insert(x-1,1);
}
else
if (cc=='Q')
{
x=getint();
y=getint();
int ans=spt.Max_sum(x,y);
printf_(ans);
// printf("%d\n",ans);
}
else
if (cc=='R')
{
x=getint();
y=getint();
spt.modify(x,y);
}
else
if (cc=='D')
{
x=getint();
spt.del(x);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: