[NOI2005]维护数列
终于过了。。调了一天了。。
嗯,记一下有哪些坑点:
首先,MAKE-SAME操作可以是设为0,这里要注意一下。
回收点的时候要注意把标记清空。
还有边界的inf要设的合理一点。
然后就没了。。我的一天啊。。
奉上我丑陋无比的代码。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cctype>
#define qmin(x,y) (x=min(x,y))
#define qmax(x,y) (x=max(x,y))
#define lch ch[root][0]
#define rch ch[root][1]
using namespace std;
inline char gc() {
// static char buf[100000],*p1,*p2;
// return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
return getchar();
}
template<class T>
int read(T &ans) {
ans=0;char ch=gc();T f=1;
while(!isdigit(ch)) {
if(ch==EOF) return -1;
if(ch=='-') f=-1;
ch=gc();
}
while(isdigit(ch))
ans=ans*10+ch-'0',ch=gc();
ans*=f;return 1;
}
template<class T1,class T2>
int read(T1 &a,T2 &b) {
return read(a)!=EOF&&read(b)!=EOF?2:EOF;
}
template<class T1,class T2,class T3>
int read(T1 &a,T2 &b,T3 &c) {
return read(a,b)!=EOF&&read(c)!=EOF?3:EOF;
}
void skip() {
char ch=gc();
while(ch!='\n'&&ch!=' ') ch=gc();
}
int get_opt() {
char ch=gc();
while(!isalpha(ch)) ch=gc();
if(ch=='M') {
gc();ch=gc();
skip();
if(ch=='K') return 3;
else return 6;
}
skip();
switch(ch) {
case 'I' : return 1;
case 'D' : return 2;
case 'R' : return 4;
case 'G' : return 5;
}
}
typedef long long ll;
const int Maxn=510000;
const int inf=0x3f3f3f3f;
ll seed=20020414;
int rand() {
seed^=seed<<32,seed^=seed>>15,seed^=seed<<3;
return seed=((seed^1360893662)+371122200)*204140019+1098900342&0x7fffffff;
}
int ch[Maxn][2],siz[Maxn],lm[Maxn],rm[Maxn],dat[Maxn],sum[Maxn],ma[Maxn];
int rot,x,n,m,a[Maxn],rnd[Maxn],flag[Maxn],bj[Maxn],st[Maxn],pos,k,lt,rt,mt;
int q[Maxn],top;
void update(int root) {
siz[root]=siz[lch]+siz[rch]+1;
sum[root]=sum[lch]+sum[rch]+dat[root];
lm[root]=max(lm[lch],sum[lch]+dat[root]+lm[rch]);
rm[root]=max(rm[rch],sum[rch]+dat[root]+rm[lch]);
ma[root]=lm[rch]+dat[root]+rm[lch];
if(lch) qmax(ma[root],ma[lch]);
if(rch) qmax(ma[root],ma[rch]);
}
int newnode(int x) {
int root=q[top--];
lch=rch=0;
rnd[root]=rand();
dat[root]=x;
bj[root]=2333,flag[root]=0;
update(root);
return root;
}
void pushr(int root) {
if(!root) return;
flag[root]^=1;
swap(lch,rch);
swap(lm[root],rm[root]);
}
void abj(int root,int x) {
if(!root) return;
bj[root]=x;
sum[root]=siz[root]*x;
dat[root]=x;
rm[root]=lm[root]=max(0,sum[root]);
ma[root]=max(x,sum[root]);
}
void pushdown(int root) {
if(bj[root]!=2333) {
abj(lch,bj[root]);
abj(rch,bj[root]);
bj[root]=2333,flag[root]=0;
}
if(flag[root]) {
flag[root]=0;
pushr(lch),pushr(rch);
}
}
int merge(int a,int b) {
if(!a||!b) return a+b;int root;
if(rnd[a]<rnd[b]) root=a,pushdown(root),rch=merge(rch,b);
else root=b,pushdown(root),lch=merge(a,lch);update(root);return root;
}
void split(int root,int &a,int &b,int x) {
if(!root) {a=b=0;return;}
if(!x) {b=root,a=0;return;}
pushdown(root);
if(siz[lch]<x) a=root,split(rch,rch,b,x-siz[lch]-1);
else b=root,split(lch,a,lch,x);update(root);
}
int build(int x) {
int zhy=1;
st[1]=newnode(a[1]);
for(int i=2;i<=x;i++) {
int root=newnode(a[i]);
while(zhy&&rnd[st[zhy]]>=rnd[root]) lch=st[zhy--],update(lch);
update(root);if(zhy) ch[st[zhy]][1]=root,update(st[zhy]);
st[++zhy]=root;
}
while(zhy) update(st[zhy--]);
return st[1];
}
void del(int root) {
q[++top]=root;
if(lch) del(lch);
if(rch) del(rch);
}
void insert() {
read(pos,k);if(!k) return;
for(int i=1;i<=k;i++) read(a[i]);
split(rot,lt,rt,pos+1);
rot=merge(merge(lt,build(k)),rt);
}
void del() {
read(pos,k);if(!k) return;
split(rot,lt,rt,pos);
split(rt,mt,rt,k);
rot=merge(lt,rt);
del(mt);
}
void chan() {
read(pos,k,x);if(!k) return;
split(rot,lt,rt,pos);
split(rt,mt,rt,k);
abj(mt,x);
rot=merge(merge(lt,mt),rt);
}
void rev() {
read(pos,k);if(!k) return;
split(rot,lt,rt,pos);
split(rt,mt,rt,k);
pushr(mt);
rot=merge(merge(lt,mt),rt);
}
void gsum() {
read(pos,k);if(!k) {puts("0");return;}
split(rot,lt,rt,pos);
split(rt,mt,rt,k);
printf("%d\n",sum[mt]);
rot=merge(merge(lt,mt),rt);
}
void gmax() {
printf("%d\n",ma[rot]);
}
void print(int root) {
if(!root) return;
printf("(");
print(lch);
printf(")");
printf("%d",dat[root]);
printf("{");
print(rch);
printf("}");
}
signed main() {
// freopen("test.in","r",stdin);
// freopen("out","w",stdout);
read(n,m);a[1]=-510000000;
for(int i=1;i<=n;i++) read(a[i+1]);a[n+2]=-510000000;
for(int i=1;i<510000;i++) q[++top]=i;
rot=build(n+2);
// print(rot);putchar('\n');
while(m--) {
switch(get_opt()) {
case 1 : insert();break;
case 2 : del();break;
case 3 : chan();break;
case 4 : rev();break;
case 5 : gsum();break;
case 6 : gmax();break;
}
}
// update(rot);
// print(rot);putchar('\n');
return 0;
}