http://blog.csdn.net/drazxlnddt/article/details/51051598

flip为true表示以当前节点为根的子树需要交换。set为true表示以当前节点为根的子树(包括自身)需要全部设为setv。

有个大坑:所谓和最大的子列最少有一个元素。有些操作可能对空的序列操作。

错误记录:所有注释掉的(多余的)和在之后加了//的语句(少的)

30和31行是为了更新子节点维护的各个值到正确的值(其他情况在split和merge中都是已经完成了更新,但如果字节点有setv的话没有)

附:一般的线段树维护时候,lazytag都是表示当前节点已经完成某操作,其所有子节点需要进行此操作。

也就是说,按照正确方法访问到某节点(root,或是split或merge出的节点,或是父节点访问子节点等),那么其权值一定已经是对的了,不用额外的upd()。但是这里set的tag定义为当前节点未完成此操作,要对当前节点及所有子节点完成。flip的操作,对于自身节点是没有影响的,因此flip的tag无所谓。因此需要要30和31行。原因嘛。。不知道。

上面都是假的!!!记住了只要pushdown()会改变upd()用到的参数,都必须要加上这两行,即使没有,为了防止漏看什么的也可以加上

注意53-55


可喜可贺,成功用自己A不掉的程序拍爆了A掉的程序(就是以下程序)

5 3
7 -1 -4 2 10
DELETE 1 4
MAKE-SAME 1 1 8
MAX-SUM

 #include<cstdio>
#include<algorithm>
#include<ctime>
using namespace std;
template<typename T>
class MyVec
{
private:
static const int M_SIZE=;
int rand1()
{
static int x=;
return x=(48271LL*x+)%;
}
public:
static const T zero=T();
struct Node
{
Node(){}
Node* ch[];
int r;
bool flip,set;
T v;
T setv;
int size;
T sum;
T max_sum[];//0=>left,1=>right,2=>this
void upd()
{
if(ch[]) ch[]->pushdown();//
if(ch[]) ch[]->pushdown();//
size=+(ch[]?ch[]->size:)+(ch[]?ch[]->size:);
sum=v+(ch[]?ch[]->sum:zero)+(ch[]?ch[]->sum:zero);
max_sum[]=max(ch[]?ch[]->max_sum[]:zero,v+(ch[]?ch[]->sum:zero)+(ch[]?ch[]->max_sum[]:zero));
max_sum[]=max(ch[]?ch[]->max_sum[]:zero,v+(ch[]?ch[]->sum:zero)+(ch[]?ch[]->max_sum[]:zero));
// max_sum[2]=max(max(ch[0]?ch[0]->max_sum[2]:zero,ch[1]?ch[1]->max_sum[2]:zero),v+(ch[0]?ch[0]->max_sum[1]:zero)+(ch[1]?ch[1]->max_sum[0]:zero));
max_sum[]=v+(ch[]?ch[]->max_sum[]:zero)+(ch[]?ch[]->max_sum[]:zero);
if(ch[]) max_sum[]=max(max_sum[],ch[]->max_sum[]);
if(ch[]) max_sum[]=max(max_sum[],ch[]->max_sum[]);
}
void pushdown()
{
if(flip)
{
swap(ch[],ch[]);
swap(max_sum[],max_sum[]);//
if(ch[]) (ch[]->flip)^=;
if(ch[]) (ch[]->flip)^=;
flip=;
}
if(set)
{
v=setv;//
sum=v*size;//
//max_sum[0]=max_sum[1]=max_sum[2]=v>0 ? v*size : 0;//
max_sum[]=max_sum[]=v> ? sum : ;
max_sum[]=v> ? sum : v;
if(ch[])
{
//ch[0]->v=setv;
ch[]->setv=setv;
ch[]->set=;
}
if(ch[])
{
//ch[1]->v=setv;
ch[]->setv=setv;
ch[]->set=;
}
set=;
}
}
}nodes[M_SIZE];
Node* root;
Node* que[M_SIZE];
int que_top;
Node* getnode()
{
return que[que_top--];
}
void delnode(Node* x)
{
que[++que_top]=x;
}
Node* merge(Node* a,Node* b)
{
if(a==NULL) return b;
if(b==NULL) return a;
if(a->r < b->r)
{
a->pushdown();a->ch[]=merge(a->ch[],b);a->upd();
return a;
}
else
{
b->pushdown();b->ch[]=merge(a,b->ch[]);b->upd();
return b;
}
}
//注意upd()
typedef pair<Node*,Node*> P;
P split(Node* a,int n)
{
if(a==NULL) return P(NULL,NULL);
P y;
a->pushdown();int s=a->ch[] ? a->ch[]->size : ;//
if(s>=n)
{
y=split(a->ch[],n);
a->ch[]=y.second;a->upd();
y.second=a;
}
else
{
y=split(a->ch[],n-s-);
a->ch[]=y.first;a->upd();
y.first=a;
}
return y;
}
Node* kth(Node* o,int k)
{
if(o==NULL||k<=||k > o->size) return NULL;
P y=split(root,k-);
P y2=split(y.second,);
root=merge(merge(y.first,y2.first),y2.second);
return y2.first;
}
void erase(Node* &o,int k)
{
if(o==NULL||k<=||k > o->size) return;
P y=split(root,k-);
P y2=split(y.second,);
delnode(y2.first);
root=merge(y.first,y2.second);
}
void deltree(Node* o)
{
if(o->ch[]) deltree(o->ch[]);
if(o->ch[]) deltree(o->ch[]);
delnode(o);
}
T find_max_sum()
{
return root?root->max_sum[]:zero;
}
public:
//在第k个之前插入
void insert(int k,const T& x)
{
Node* t=getnode();
t->ch[]=t->ch[]=NULL;t->r=rand1();t->v=x;t->flip=;t->set=;t->setv=zero;t->upd();
P y=split(root,k-);
root=merge(merge(y.first,t),y.second);
}
void insert(int k,Node* x)
{
P y=split(root,k-);
root=merge(merge(y.first,x),y.second);
}
MyVec()
{
que_top=M_SIZE-;
for(int i=;i<M_SIZE;i++) que[i]=nodes+i;
root=NULL;
}
void push_back(const T& x)
{
insert(size()+,x);
}
void pop_back()
{
erase(root,root->size);
}
void push_front(const T& x)
{
insert(,x);
}
void pop_front()
{
erase(root,);
}
Node* find_by_order(int k)
{
return kth(root,k);
}
T& operator[](int k)
{
return kth(root,k)->v;
}
void erase(int k)
{
erase(root,k);
}
//第k个开始删连续p个
void erase(int k,int p)
{
P y=split(root,k-);
P y2=split(y.second,p);
root=merge(y.first,y2.second);
deltree(y2.first);
}
int size()
{
return root ? root->size : ;
}
//翻转[l,r]
void reverse(int l,int r)
{
if(l>r) return;//
P y=split(root,l-);
P y2=split(y.second,r-l+);
//y2.first->pushdown();//
y2.first->flip^=;
//y2.first->upd();
root=merge(merge(y.first,y2.first),y2.second);
}
Node* build(T *l,T *r)
{
if(l>r) return NULL;
if(l==r)
{
Node* t=getnode();
t->ch[]=t->ch[]=NULL;t->r=rand1();t->v=*l;t->flip=;t->set=;t->setv=zero;t->upd();
return t;
}
else
{
T* mid=l+(r-l)/;
return merge(build(l,mid),build(mid+,r));
}
}
T sum(int l,int r)
{
if(l>r) return zero;//
P y=split(root,l-);
P y2=split(y.second,r-l+);
//y2.first->upd();//
T ans=y2.first->sum;
root=merge(merge(y.first,y2.first),y2.second);
return ans;
}
void set(int l,int r,const T& x)
{
if(l>r) return;//
P y=split(root,l-);
P y2=split(y.second,r-l+);
//y2.first->pushdown();
y2.first->set=;
y2.first->setv=x;
//y2.first->v=x;
//y2.first->upd();
root=merge(merge(y.first,y2.first),y2.second);
}
};
MyVec<int> x;
int n,m,l,r;
int a[];
char ope[];
int main()
{
//freopen("testdata.in","r",stdin);
//freopen("testdata.out","w",stdout);
int i,posi,tot,c;
MyVec<int>::Node* t;
scanf("%d%d",&n,&m);
for(i=;i<=n;i++)
scanf("%d",&a[i]);
x.root=x.build(a+,a+n);
while(m--)
{
scanf("%s",ope);
if(ope[]=='S')
{
scanf("%d%d",&posi,&tot);
for(i=;i<=tot;i++) scanf("%d",&a[i]);
t=x.build(a+,a+tot);
x.insert(posi+,t);
}
else if(ope[]=='L')
{
scanf("%d%d",&posi,&tot);
x.erase(posi,tot);
}
else if(ope[]=='K')
{
scanf("%d%d%d",&posi,&tot,&c);
x.set(posi,posi+tot-,c);
}
else if(ope[]=='V')
{
scanf("%d%d",&posi,&tot);
x.reverse(posi,posi+tot-);
}
else if(ope[]=='T')
{
scanf("%d%d",&posi,&tot);
printf("%d\n",x.sum(posi,posi+tot-));
}
else if(ope[]=='X')
{
printf("%d\n",x.find_max_sum());
}
//printf("%s %d %d %d\n",ope,posi,m,a[1]);
//for(i=1;i<=x.size();i++) printf("%d ",x[i]);puts("");
}
return ;
}
 #pragma GCC optimize(2)
#include<cstdio>
#include<algorithm>
#include<ctime>
using namespace std;
template<typename T>
class MyVec
{
private:
static const int M_SIZE=;
int rand1()
{
static int x=;
return x=(48271LL*x+)%;
}
public:
static const T zero=T();
struct Node
{
Node(){}
Node* ch[];
int r;
bool flip,set;
T v;
T setv;
int size;
T sum;
T max_sum[];
void upd()
{
if(ch[]) ch[]->pushdown();
if(ch[]) ch[]->pushdown();
size=+(ch[]?ch[]->size:)+(ch[]?ch[]->size:);
sum=v+(ch[]?ch[]->sum:zero)+(ch[]?ch[]->sum:zero);
max_sum[]=max(ch[]?ch[]->max_sum[]:zero,v+(ch[]?ch[]->sum:zero)+(ch[]?ch[]->max_sum[]:zero));
max_sum[]=max(ch[]?ch[]->max_sum[]:zero,v+(ch[]?ch[]->sum:zero)+(ch[]?ch[]->max_sum[]:zero));
max_sum[]=v+(ch[]?ch[]->max_sum[]:zero)+(ch[]?ch[]->max_sum[]:zero);
if(ch[]) max_sum[]=max(max_sum[],ch[]->max_sum[]);
if(ch[]) max_sum[]=max(max_sum[],ch[]->max_sum[]);
}
void pushdown()
{
if(flip)
{
swap(ch[],ch[]);
swap(max_sum[],max_sum[]);
if(ch[]) (ch[]->flip)^=;
if(ch[]) (ch[]->flip)^=;
flip=;
}
if(set)
{
v=setv;
sum=v*size;
max_sum[]=max_sum[]=v> ? sum : ;
max_sum[]=v> ? sum : v;
if(ch[])
{
ch[]->setv=setv;
ch[]->set=;
}
if(ch[])
{
ch[]->setv=setv;
ch[]->set=;
}
set=;
}
}
}nodes[M_SIZE];
Node* root;
Node* que[M_SIZE];
int que_top;
Node* getnode()
{
return que[que_top--];
}
void delnode(Node* x)
{
que[++que_top]=x;
}
Node* merge(Node* a,Node* b)
{
if(a==NULL) return b;
if(b==NULL) return a;
if(a->r < b->r)
{
a->pushdown();a->ch[]=merge(a->ch[],b);a->upd();
return a;
}
else
{
b->pushdown();b->ch[]=merge(a,b->ch[]);b->upd();
return b;
}
}
typedef pair<Node*,Node*> P;
P split(Node* a,int n)
{
if(a==NULL) return P(NULL,NULL);
P y;
a->pushdown();int s=a->ch[] ? a->ch[]->size : ;//
if(s>=n)
{
y=split(a->ch[],n);
a->ch[]=y.second;a->upd();
y.second=a;
}
else
{
y=split(a->ch[],n-s-);
a->ch[]=y.first;a->upd();
y.first=a;
}
return y;
}
Node* kth(Node* o,int k)
{
if(o==NULL||k<=||k > o->size) return NULL;
P y=split(root,k-);
P y2=split(y.second,);
root=merge(merge(y.first,y2.first),y2.second);
return y2.first;
}
void erase(Node* &o,int k)
{
if(o==NULL||k<=||k > o->size) return;
P y=split(root,k-);
P y2=split(y.second,);
delnode(y2.first);
root=merge(y.first,y2.second);
}
void deltree(Node* o)
{
if(o->ch[]) deltree(o->ch[]);
if(o->ch[]) deltree(o->ch[]);
delnode(o);
}
T find_max_sum()
{
return root?root->max_sum[]:zero;
}
public:
void insert(int k,const T& x)
{
Node* t=getnode();t->ch[]=t->ch[]=NULL;t->r=rand1();t->v=x;t->flip=;t->set=;t->setv=zero;t->upd();
P y=split(root,k-);
root=merge(merge(y.first,t),y.second);
}
void insert(int k,Node* x)
{
P y=split(root,k-);
root=merge(merge(y.first,x),y.second);
}
MyVec()
{
que_top=M_SIZE-;
for(int i=;i<M_SIZE;i++) que[i]=nodes+i;
root=NULL;
}
void erase(int k,int p)
{
P y=split(root,k-);
P y2=split(y.second,p);
root=merge(y.first,y2.second);
deltree(y2.first);
}
void reverse(int l,int r)
{
if(l>r) return;
P y=split(root,l-);
P y2=split(y.second,r-l+);
y2.first->flip^=;
root=merge(merge(y.first,y2.first),y2.second);
}
Node* build(T *l,T *r)
{
if(l>r) return NULL;
if(l==r)
{
Node* t=getnode();t->ch[]=t->ch[]=NULL;t->r=rand1();t->v=*l;t->flip=;t->set=;t->setv=zero;t->upd();
return t;
}
else
{
T* mid=l+(r-l)/;
return merge(build(l,mid),build(mid+,r));
}
}
T sum(int l,int r)
{
if(l>r) return zero;
P y=split(root,l-);
P y2=split(y.second,r-l+);
T ans=y2.first->sum;
root=merge(merge(y.first,y2.first),y2.second);
return ans;
}
void set(int l,int r,const T& x)
{
if(l>r) return;
P y=split(root,l-);
P y2=split(y.second,r-l+);
y2.first->set=;
y2.first->setv=x;
root=merge(merge(y.first,y2.first),y2.second);
}
};
MyVec<int> x;
int n,m,l,r;
int a[];
char ope[];
int main()
{
int i,posi,tot,c;
MyVec<int>::Node* t;
scanf("%d%d",&n,&m);
for(i=;i<=n;i++)scanf("%d",&a[i]);
x.root=x.build(a+,a+n);
while(m--)
{
scanf("%s",ope);
if(ope[]=='S') {scanf("%d%d",&posi,&tot);for(i=;i<=tot;i++) scanf("%d",&a[i]);t=x.build(a+,a+tot);x.insert(posi+,t);}
else if(ope[]=='L'){scanf("%d%d",&posi,&tot);x.erase(posi,tot);}
else if(ope[]=='K'){scanf("%d%d%d",&posi,&tot,&c);x.set(posi,posi+tot-,c);}
else if(ope[]=='V'){scanf("%d%d",&posi,&tot);x.reverse(posi,posi+tot-);}
else if(ope[]=='T'){scanf("%d%d",&posi,&tot);printf("%d\n",x.sum(posi,posi+tot-));}
else if(ope[]=='X'){printf("%d\n",x.find_max_sum());}
}
return ;
}

重写了

 #pragma GCC optimize(3)
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
namespace S
{
const int N=;
struct I
{
bool ok;
int l,r,a;
int sz,sum;
}emp;
I operator+(const I &a,const I &b)
{
if(!a.ok) return b;
if(!b.ok) return a;
I c;c.ok=;
c.sz=a.sz+b.sz;
c.sum=a.sum+b.sum;
//c.maxn=max(a.maxn,b.maxn);
c.l=max(a.l,a.sum+b.l);
c.r=max(b.r,b.sum+a.r);
c.a=max(max(a.a,b.a),max(max(c.l,c.r),a.r+b.l));
return c;
}
struct Node
{
Node *ch[];
I all,self;int d,r;
bool flip,set;int setv;
}nds[N];
I genself(Node *a)
{
I ans;ans.ok=;
ans.l=ans.r=ans.a=a->d;
ans.sz=;ans.sum=/*ans.maxn=*/a->d;
return ans;
}
I genmore(const I &a,int b)
{
I ans=a;
if(a.sum>=)
{
ans.a=ans.a*b;
ans.l=ans.l*b;
ans.r=ans.r*b;
}
ans.sz*=b;ans.sum*=b;
return ans;
}
const I &gall(Node *a) {return a?a->all:emp;}
void doset(Node *a,int b)
{
if(!a) return;
a->d=b;a->self=genself(a);
a->all=genmore(a->self,a->all.sz);
a->set=;a->setv=b;
}
void doflip(Node *a)
{
if(!a) return;
swap(a->ch[],a->ch[]);
swap(a->all.l,a->all.r);
a->flip^=;
}
void pd(Node *a)
{//if(!a) return;
if(a->flip)
{
doflip(a->ch[]);
doflip(a->ch[]);
a->flip=;
}
if(a->set)
{
doset(a->ch[],a->setv);
doset(a->ch[],a->setv);
a->set=;
}
}
void upd(Node *a)
{//pd(a->ch[0]);pd(a->ch[1]);
a->self=genself(a);
a->all=gall(a->ch[])+a->self+gall(a->ch[]);
}
queue<Node*> q;
void init()
{
for(int i=;i<N;i++) q.push(nds+i);
}
int rand1()
{
static int x=;
return x=(48271LL*x+)%;
}
Node *getnode()
{
Node *t=q.front();q.pop();
t->ch[]=t->ch[]=;t->d=;t->r=rand1();
t->flip=t->set=;t->setv=;//t->all=t->rall=t->self=emp;
return t;
}
void delnode(Node *a) {q.push(a);}
void deltree(Node *a)
{
if(!a) return;
deltree(a->ch[]);deltree(a->ch[]);
delnode(a);
}
Node *merge(Node *a,Node *b)
{
if(!a) return b;
if(!b) return a;
if(a->r<b->r)
{
pd(a);a->ch[]=merge(a->ch[],b);upd(a);
return a;
}
else
{
pd(b);b->ch[]=merge(a,b->ch[]);upd(b);
return b;
}
}
typedef pair<Node*,Node*> pnn;
pnn split(Node *o,int k)
{
if(!o) return pnn(,);
if(!k) return pnn(,o);
pd(o);int ls=gall(o->ch[]).sz;pnn y;
if(k<=ls)
{
y=split(o->ch[],k);
o->ch[]=y.se;upd(o);
y.se=o;
}
else
{
y=split(o->ch[],k-ls-);
o->ch[]=y.fi;upd(o);
y.fi=o;
}
return y;
}
Node *build(int *l,int *r)
{
if(l==r)
{
Node *t=getnode();t->d=*l;upd(t);
return t;
}
int *mid=l+((r-l)>>);
return merge(build(l,mid),build(mid+,r));
}
}
using S::Node;
using S::pnn;
using S::merge;
using S::split;
using S::build;
Node *rt;
int n,m,a[];
char tmp[];
int main()
{
S::init();
int i,j,p,tot,x,ans;Node *t1;pnn ta,tb;
scanf("%d%d",&n,&m);
for(i=;i<=n;i++) scanf("%d",&a[i]);
rt=build(a+,a+n);
for(i=;i<=m;i++)
{
scanf("%s",tmp);
if(tmp[]=='I')
{
scanf("%d%d",&p,&tot);
if(tot==) continue;
for(j=;j<=tot;j++) scanf("%d",&a[j]);
t1=build(a+,a+tot);
ta=split(rt,p);
rt=merge(merge(ta.fi,t1),ta.se);
}
else if(tmp[]=='D')
{
scanf("%d%d",&p,&tot);
if(tot==) continue;
ta=split(rt,p-);tb=split(ta.se,tot);
S::deltree(tb.fi);
rt=merge(ta.fi,tb.se);
}
else if(tmp[]=='M'&&tmp[]=='K')
{
scanf("%d%d%d",&p,&tot,&x);
if(tot==) continue;
ta=split(rt,p-);tb=split(ta.se,tot);
S::doset(tb.fi,x);
rt=merge(ta.fi,merge(tb.fi,tb.se));
}
else if(tmp[]=='R')
{
scanf("%d%d",&p,&tot);
if(tot==) continue;
ta=split(rt,p-);tb=split(ta.se,tot);
S::doflip(tb.fi);
rt=merge(ta.fi,merge(tb.fi,tb.se));
}
else if(tmp[]=='G')
{
scanf("%d%d",&p,&tot);
if(tot==) {printf("0\n");continue;}
ta=split(rt,p-);tb=split(ta.se,tot);
ans=tb.fi->all.sum;
rt=merge(ta.fi,merge(tb.fi,tb.se));
printf("%d\n",ans);
}
else
{
printf("%d\n",rt->all.a);
}
}
return ;
}

卡常后才能bzojA

 #pragma GCC optimize(3)
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
namespace S
{
const int N=;
struct I
{
int l,r,a;
int sum;
};
I operator+(const I &a,const I &b)
{
I c;
c.sum=a.sum+b.sum;
//c.maxn=max(a.maxn,b.maxn);
c.l=max(a.l,a.sum+b.l);
c.r=max(b.r,b.sum+a.r);
c.a=max(max(a.a,b.a),max(max(c.l,c.r),a.r+b.l));
return c;
}
struct Node
{
Node *ch[];
I all;int d,r,sz;
bool flip,set;int setv;
}nds[N];
int gsz(Node *o) {return o?o->sz:;}
void doset(Node *a,int b)
{
if(!a) return;
a->d=b;
static I self;
self.l=self.r=self.a=a->d;
self.sum=/*self.maxn=*/a->d;
int sz=a->sz;
a->all=self;
if(self.sum>=) a->all.a*=sz,a->all.l*=sz,a->all.r*=sz;
a->all.sum*=sz;
a->set=;a->setv=b;
}
void doflip(Node *a)
{
if(!a) return;
swap(a->ch[],a->ch[]);
swap(a->all.l,a->all.r);
a->flip^=;
}
void pd(Node *a)
{//if(!a) return;
if(a->flip)
{
doflip(a->ch[]);
doflip(a->ch[]);
a->flip=;
}
if(a->set)
{
doset(a->ch[],a->setv);
doset(a->ch[],a->setv);
a->set=;
}
}
void upd(Node *a)
{//pd(a->ch[0]);pd(a->ch[1]);
a->sz=gsz(a->ch[])++gsz(a->ch[]);
static I self;
self.l=self.r=self.a=a->d;
self.sum=/*self.maxn=*/a->d;
if(a->ch[]&&a->ch[])
a->all=a->ch[]->all+self+a->ch[]->all;
else if(a->ch[])
a->all=a->ch[]->all+self;
else if(a->ch[])
a->all=self+a->ch[]->all;
else
a->all=self;
}
queue<Node*> q;
void init()
{
for(int i=;i<N;i++) q.push(nds+i);
}
int rand1()
{
static int x=;
return x=(48271LL*x+)%;
}
Node *getnode()
{
Node *t=q.front();q.pop();
t->ch[]=t->ch[]=;t->d=;t->r=rand1();
t->flip=t->set=;t->setv=;//t->all=t->rall=t->self=emp;
return t;
}
void delnode(Node *a) {q.push(a);}
void deltree(Node *a)
{
if(!a) return;
deltree(a->ch[]);deltree(a->ch[]);
delnode(a);
}
Node *merge(Node *a,Node *b)
{
if(!a) return b;
if(!b) return a;
if(a->r<b->r)
{
pd(a);a->ch[]=merge(a->ch[],b);upd(a);
return a;
}
else
{
pd(b);b->ch[]=merge(a,b->ch[]);upd(b);
return b;
}
}
typedef pair<Node*,Node*> pnn;
pnn split(Node *o,int k)
{
if(!o) return pnn(,);
if(!k) return pnn(,o);
pd(o);int ls=gsz(o->ch[]);pnn y;
if(k<=ls)
{
y=split(o->ch[],k);
o->ch[]=y.se;upd(o);
y.se=o;
}
else
{
y=split(o->ch[],k-ls-);
o->ch[]=y.fi;upd(o);
y.fi=o;
}
return y;
}
Node *build(int *l,int *r)
{
if(l==r)
{
Node *t=getnode();t->d=*l;upd(t);
return t;
}
int *mid=l+((r-l)>>);
return merge(build(l,mid),build(mid+,r));
}
}
using S::Node;
using S::pnn;
using S::merge;
using S::split;
using S::build;
Node *rt;
int n,m,a[];
char tmp[];
int main()
{
srand();S::init();
int i,j,p,tot,x,ans;Node *t1;pnn ta,tb;
scanf("%d%d",&n,&m);
for(i=;i<=n;i++) scanf("%d",&a[i]);
rt=build(a+,a+n);
for(i=;i<=m;i++)
{
scanf("%s",tmp);
if(tmp[]=='I')
{
scanf("%d%d",&p,&tot);
if(tot==) continue;
for(j=;j<=tot;j++) scanf("%d",&a[j]);
t1=build(a+,a+tot);
ta=split(rt,p);
rt=merge(merge(ta.fi,t1),ta.se);
}
else if(tmp[]=='D')
{
scanf("%d%d",&p,&tot);
if(tot==) continue;
ta=split(rt,p-);tb=split(ta.se,tot);
S::deltree(tb.fi);
rt=merge(ta.fi,tb.se);
}
else if(tmp[]=='M'&&tmp[]=='K')
{
scanf("%d%d%d",&p,&tot,&x);
if(tot==) continue;
ta=split(rt,p-);tb=split(ta.se,tot);
S::doset(tb.fi,x);
rt=merge(ta.fi,merge(tb.fi,tb.se));
}
else if(tmp[]=='R')
{
scanf("%d%d",&p,&tot);
if(tot==) continue;
ta=split(rt,p-);tb=split(ta.se,tot);
S::doflip(tb.fi);
rt=merge(ta.fi,merge(tb.fi,tb.se));
}
else if(tmp[]=='G')
{
scanf("%d%d",&p,&tot);
if(tot==) {printf("0\n");continue;}
ta=split(rt,p-);tb=split(ta.se,tot);
ans=tb.fi->all.sum;
rt=merge(ta.fi,merge(tb.fi,tb.se));
printf("%d\n",ans);
}
else
{
printf("%d\n",rt->all.a);
}
}
return ;
}

洛谷 P2042 维护数列的更多相关文章

  1. 洛谷 P2042 [NOI2005]维护数列-Splay(插入 删除 修改 翻转 求和 最大的子序列)

    因为要讲座,随便写一下,等讲完有时间好好写一篇splay的博客. 先直接上题目然后贴代码,具体讲解都写代码里了. 参考的博客等的链接都贴代码里了,有空再好好写. P2042 [NOI2005]维护数列 ...

  2. [洛谷P3228] [HNOI2013]数列

    洛谷题目链接:[HNOI2013]数列 题目描述 小T最近在学着买股票,他得到内部消息:F公司的股票将会疯涨.股票每天的价格已知是正整数,并且由于客观上的原因,最多只能为N.在疯涨的K天中小T观察到: ...

  3. BZOJ 1500 洛谷2042维护序列题解

    BZ链接 洛谷链接 这道题真是丧心病狂.... 应该很容易就可以看出做法,但是写代码写的....... 思路很简单,用一个平衡树维护一下所有的操作就好了,重点讲解一下代码的细节 首先如果按照常规写法的 ...

  4. 【洛谷 P1667】 数列 (贪心)

    题目链接 对于一个区间\([x,y]\),设这个区间的总和为\(S\) 那么我们在前缀和(设为\(sum[i]\))的意义上考虑到原操作其实就是\(sum[x−1]+=S\) , \(sum[x]+S ...

  5. 洛谷 P2042 【[NOI2005]维护数列】

    一直在想要做这道题,但是被那个硕大的Splay标签压垮了 好了,切入正题 这道题应该是我第二次用splay来维护区间问题 我还是太菜了QAQ 其实思路也很简单,就是以每一个位置的下标来进行维护,然后其 ...

  6. 【洛谷P2042】维护数列

    题目大意:维护一个序列,支持区间插入,区间删除,区间翻转,查询区间元素和,查询区间最大子段和操作. 题解:毒瘤题...QAQ打完这道题发现自己以前学了一个假的 Splay.. 对于区间操作,用 spl ...

  7. 洛谷P2042 [NOI2005]维护数列

    #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #in ...

  8. 【洛谷 P2042】 [NOI2005]维护数列(自闭记第一期)

    题目链接 首先,这题我是没A的..太毒瘤了 题目本身不难,都是\(Splay\)的基操,但是细节真的容易挂. 调了好久自闭了,果断放弃.. 希望本节目停更. 放上最终版本 #include <c ...

  9. 洛谷P1415 拆分数列[序列DP 状态 打印]

    题目背景 [为了响应党中央勤节俭.反铺张的精神,题目背景描述故事部分略去^-^] 题目描述 给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数.如果有多组解,则输出使得最后一个数最小的同时 ...

随机推荐

  1. 【转】nginx 和 php-fpm 通信使用unix socket还是TCP,及其配置

    原文: http://blog.csdn.net/pcyph/article/details/46513521 -------------------------------------------- ...

  2. kd树 hdu2966 In case of failure

    传送门:pid=2966" target="_blank">点击打开链接 题意:给n个点,求对于每一个点到近期点的欧几里德距离的平方. 思路:看鸟神博客学kd树劲啊 ...

  3. ES文件浏览器 WIFI 查看电脑文件怎么弄

    1 开启来宾账户   2 右击要共享的文件夹,添加Guest共享(如果只是要查看共享的资源,权限级别为读取即可)   3 共享之后,网络路径就是"\\"+你的计算机名+" ...

  4. poj 1426 Find The Multiple ( BFS+同余模定理)

    Find The Multiple Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18390   Accepted: 744 ...

  5. System.Diagnostics.Debug.WriteLine 在OutPut中无输出

    TextWriterTraceListener writer = new TextWriterTraceListener(System.Console.Out);              Debug ...

  6. 【Mongodb教程 第九课 】MongoDB 删除文档

    remove() 方法 MongoDB的 remove() 方法用于从集合中删除文档.remove() 方法接受两个参数.第一个是删除criteria ,第二是justOne标志: deletion ...

  7. 在云服务器 ECS Linux CentOS 7 下重启服务不再通过 service 操作,而是通过 systemctl 操作

    在云服务器 ECS Linux CentOS 7 下重启服务不再通过 service  操作,而是通过 systemctl 操作. 操作说明如下: 1. 查看 sshd 服务是否启动: 看到上述信息就 ...

  8. html2canvas 导出包含滚动条的内容

    import html2canvas from 'html2canvas'; exportPDF() { // 导出为 pdf let dom = document.querySelector('yo ...

  9. Oracle可插拔数据库的jdbc连接串写法

    我在服务器上部署某个第三方系统的数据库的时候,服务器数据库版本为oracle 12c.我采用的方式是新建了一个实例.访问正常. 后来项目的负责人告诉我,oracle12C支持所谓的可插拔数据库.可插拔 ...

  10. xcode10的那些事

    前言 这里主要介绍一下Xcode10 版本主要更新的内容.随着iOS12的发布,Xcode10已经可以从Mac App Store下载.Xcode10包含了iOS12.watchOS 5.macOS1 ...