洛谷 P2042 维护数列
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 维护数列的更多相关文章
- 洛谷 P2042 [NOI2005]维护数列-Splay(插入 删除 修改 翻转 求和 最大的子序列)
因为要讲座,随便写一下,等讲完有时间好好写一篇splay的博客. 先直接上题目然后贴代码,具体讲解都写代码里了. 参考的博客等的链接都贴代码里了,有空再好好写. P2042 [NOI2005]维护数列 ...
- [洛谷P3228] [HNOI2013]数列
洛谷题目链接:[HNOI2013]数列 题目描述 小T最近在学着买股票,他得到内部消息:F公司的股票将会疯涨.股票每天的价格已知是正整数,并且由于客观上的原因,最多只能为N.在疯涨的K天中小T观察到: ...
- BZOJ 1500 洛谷2042维护序列题解
BZ链接 洛谷链接 这道题真是丧心病狂.... 应该很容易就可以看出做法,但是写代码写的....... 思路很简单,用一个平衡树维护一下所有的操作就好了,重点讲解一下代码的细节 首先如果按照常规写法的 ...
- 【洛谷 P1667】 数列 (贪心)
题目链接 对于一个区间\([x,y]\),设这个区间的总和为\(S\) 那么我们在前缀和(设为\(sum[i]\))的意义上考虑到原操作其实就是\(sum[x−1]+=S\) , \(sum[x]+S ...
- 洛谷 P2042 【[NOI2005]维护数列】
一直在想要做这道题,但是被那个硕大的Splay标签压垮了 好了,切入正题 这道题应该是我第二次用splay来维护区间问题 我还是太菜了QAQ 其实思路也很简单,就是以每一个位置的下标来进行维护,然后其 ...
- 【洛谷P2042】维护数列
题目大意:维护一个序列,支持区间插入,区间删除,区间翻转,查询区间元素和,查询区间最大子段和操作. 题解:毒瘤题...QAQ打完这道题发现自己以前学了一个假的 Splay.. 对于区间操作,用 spl ...
- 洛谷P2042 [NOI2005]维护数列
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #in ...
- 【洛谷 P2042】 [NOI2005]维护数列(自闭记第一期)
题目链接 首先,这题我是没A的..太毒瘤了 题目本身不难,都是\(Splay\)的基操,但是细节真的容易挂. 调了好久自闭了,果断放弃.. 希望本节目停更. 放上最终版本 #include <c ...
- 洛谷P1415 拆分数列[序列DP 状态 打印]
题目背景 [为了响应党中央勤节俭.反铺张的精神,题目背景描述故事部分略去^-^] 题目描述 给出一列数字,需要你添加任意多个逗号将其拆成若干个严格递增的数.如果有多组解,则输出使得最后一个数最小的同时 ...
随机推荐
- 通过k8s(Kubernetes)搭建jmeter的压测环境master-slave架构,实现弹性伸缩
在k8s上部署jmeter的mater和slave,根据压测需求动态增减master和slave节点数量,即可以完成压测任务,又可以是资源利用最大化 https://blog.kubernauts.i ...
- leetcode笔记:Longest Substring Without Repeating Characters
一. 题目描写叙述 Given a string, find the length of the longest substring without repeating characters. For ...
- oracle获取字符串长度函数length()和lengthb()
oracle获取字符串长度函数length()和lengthb() lengthb(string)计算string所占的字节长度:返回字符串的长度,单位是字节 length(string)计算st ...
- js的几种循环语句
//js种的循环语句 //while与do while的区别是while是满足条件后才执行 //do while是不管满不满足条件都会执行一次 //for 循环与while,do while相比循环结 ...
- uml时序图的初印象-------Day64
近期有好多想法迫不及待的想去实现,但是其实是在那些最開始想的很明确,感觉会没问题的地方也总是会出现故障,导致稍微有些急躁,还是要淡定啊.又到了周末.明后天要收拾东西搬家,不知道宽带能不能顺利的给挪过去 ...
- 使用 Vagrant 构建开发环境
使用 Vagrant 构建开发环境 摘要:本文描述了如使用 Vagrant 构建统一的开发环境. 问题 作为开发人员,我们通常面临的问题有: 开发环境需要手工安装配置,这包括操作系统(CentOS.U ...
- 【iOS系列】-textView的非常规使用
[iOS系列]-textView的非常规使用 文本框坐标设置一点距离 //文本框,左边间距 textView.leftView = [[UIView alloc] initWithFrame:CGRe ...
- 偶遇HiWork,请不要擦肩而过
非常多朋友可能都不了解HiWork,在这里介绍一下. HiWork是基于云存储的团队即时沟通协作平台,主要针对于中小团队及中小企业的即时沟通,让团队沟通更顺畅.在HiWork平台可即时得知所使用第三方 ...
- 解决input,number类型的maxlength无效
使用input数字number类型的时候maxlength无效,假设需要控制输入数量为5,可以用以下方式: 无效: <input type="text" maxlength ...
- PyTorch 60 分钟入门教程:PyTorch 深度学习官方入门中文教程
什么是 PyTorch? PyTorch 是一个基于 Python 的科学计算包,主要定位两类人群: NumPy 的替代品,可以利用 GPU 的性能进行计算. 深度学习研究平台拥有足够的灵活性和速度 ...