【BZOJ 3188】【Coci 2011】Upit Splay模板题

转啊转终于转出来了,然而我的模板跟陈竞潇学长的模板一模一样,还是太弱啊,第一次用指针。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define for1(i,a,b) for(int i=(a);i<=(b);++i)
using namespace std;
typedef long long ll;
const int N=1E5+;
int n,m,data[N];
struct node{
node();
node *ch[],*fa;
ll d,sum,set,add[]; int size; short vset;
short pl() {return this==fa->ch[];}
void count(); void push();
void mark(ll,ll,short);
}*null;
node::node(){ch[]=ch[]=fa=null; size=vset=sum=add[]=add[]=;}
void node::mark(ll val,ll dd,short t){
if(this==null) return;
if(!t){
set=val;
sum=size*set;
d=set;
vset=;
add[]=add[]=;
}else{
add[]+=val;
add[]+=dd;
sum+=val*size;
sum+=dd*size*(size-)/;
d+=val+dd*(ch[]->size);
}
}
void node::push(){
if(this==null)return;
if(vset){
ch[]->mark(set,,);
ch[]->mark(set,,);
vset=; set=;
}
if(add[]||add[]){
ch[]->mark(add[],add[],);
ch[]->mark(add[]+add[]*(ch[]->size+),add[],);
add[]=add[]=;
}
}
void node::count(){
size=ch[]->size+ch[]->size+;
sum=ch[]->sum+ch[]->sum+d;
}
namespace Splay{
node *ROOT;
node *build(int l=,int r=n){
if (l>r) return null;
int mid=(l+r)>>;
node *ro=new node;
ro->d=data[mid];
ro->ch[]=build(l,mid-);
ro->ch[]=build(mid+,r);
ro->ch[]->fa=ro;
ro->ch[]->fa=ro;
ro->count();
return ro;
}
void Build(){
null=new node;
*null=node();
ROOT=build();
}
void rotate(node *k){
node *r=k->fa; if (k==null||r==null) return;
r->push(); k->push();
int x=k->pl()^;;
r->ch[x^]=k->ch[x];
r->ch[x^]->fa=r;
if (r->fa!=null) r->fa->ch[r->pl()]=k;
else ROOT=k;
k->fa=r->fa; r->fa=k;
k->ch[x]=r;
r->count(); k->count();
}
void splay(node *r,node *tar=null){
for (;r->fa!=tar;rotate(r))
if (r->fa->fa!=tar)rotate(r->pl()==r->fa->pl()?r->fa:r);
r->push();
}
void insert(int x,int val){
node *r=ROOT;
if (ROOT==null){
ROOT=new node;
ROOT->d=val;
ROOT->count();
return;
}
while ()
{
r->push();
int c;
if (r->ch[]->size+>=x) c=;
else c=,x-=r->ch[]->size+;
if (r->ch[c]==null){
r->ch[c]=new node;
r->ch[c]->fa=r;
r->ch[c]->d=val;
splay(r->ch[c]);
return;
}else r=r->ch[c];
}
}
node *kth(int k){
node *r=ROOT;
while (r!=null){
r->push();
if (r->ch[]->size>=k) r=r->ch[];
else if (r->ch[]->size+>=k) return r;
else k-=r->ch[]->size+,r=r->ch[];
}
return null;
}
node *pack(int l,int r){
node *ln=kth(l-),*rn=kth(r+);
if ((ln==null)&&(rn==null)) return ROOT;
else if (ln==null){
splay(rn); return rn->ch[];
}else if (rn==null){
splay(ln); return ln->ch[];
}else{
splay(ln); splay(rn,ROOT);
return rn->ch[];
}
}
}
int main(){
scanf("%d%d",&n,&m);
for1(i,,n)scanf("%d",&data[i]);
Splay::Build(); int j,a,b,c;
for1(i,,m){
scanf("%d",&j);
switch(j){
node *r;
case :
scanf("%d%d%d",&a,&b,&c);
r=Splay::pack(a,b);
r->mark(c,,);
Splay::splay(r);
break;
case :
scanf("%d%d%d",&a,&b,&c);
r=Splay::pack(a,b);
r->mark(c,c,);
Splay::splay(r);
break;
case :
scanf("%d%d",&a,&b);
Splay::insert(a,b);
break;
case :
scanf("%d%d",&a,&b);
r=Splay::pack(a,b);
printf("%lld\n",r->sum);
break;
}
}
return ;
}
上一篇:[Revit]开始:编写一个简单外部命令


下一篇:ARM寄存器介绍