【Splay】洛谷3372 【模板】线段树 1
Splay区间加,询问区间和。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
#define maxn 100010
#define INF 2147483647
int fa[maxn],val[maxn],c[maxn][2],root,tot,siz[maxn];
ll lazy[maxn],totalval2[maxn],val2[maxn];
void Maintain(int x)
{
siz[x]=siz[c[x][0]]+siz[c[x][1]]+1;
totalval2[x]=totalval2[c[x][0]]+totalval2[c[x][1]]+val2[x];
}
void mark(int x,ll delta){
if(x){
lazy[x]+=delta;
totalval2[x]+=(ll)siz[x]*delta;
val2[x]+=delta;
}
}
void pushdown(int x){
if(lazy[x]){
mark(c[x][0],lazy[x]);
mark(c[x][1],lazy[x]);
lazy[x]=0;
// Maintain(x);
}
}
void NewNode(int &x,int Fa,int key,ll key2)
{
x=++tot;
fa[x]=Fa;
c[x][0]=c[x][1]=0;
val[x]=key;
val2[x]=totalval2[x]=key2;
siz[x]=1;
}
void Rotate(int x,bool flag)
{
int y=fa[x];
pushdown(y);
pushdown(x);
c[y][!flag]=c[x][flag];
fa[c[x][flag]]=y;
if(fa[y]){
c[fa[y]][c[fa[y]][1]==y]=x;
}
fa[x]=fa[y];
c[x][flag]=y;
fa[y]=x;
Maintain(y);
}
void Splay(int x,int goal)
{
if(!x || x==goal){
return;
}
pushdown(x);
int y;
while((y=fa[x])!=goal){
if(fa[y]==goal){
Rotate(x,c[y][0]==x);
}
else{
if((c[y][0]==x)==(c[fa[y]][0]==y)){
Rotate(y,c[fa[y]][0]==y);
}
else{
Rotate(x,c[y][0]==x);
y=fa[x];
}
Rotate(x,c[y][0]==x);
}
}
Maintain(x);
if(!goal){
root=x;
}
}
int Find(int key,int x=root)
{
while(c[x][val[x]<key]){
if(val[x]==key){
return x;
}
x=c[x][val[x]<key];
}
return x;
}
void Insert(int key,ll key2)
{
if(!root){
NewNode(root,0,key,key2);
return;
}
int x=Find(key);
NewNode(c[x][val[x]<key],x,key,key2);
Splay(c[x][val[x]<key],0);
}
int n,m;
int main(){
int op,x,y;
ll z;
scanf("%d%d",&n,&m);
Insert(0,1ll);
for(int i=1;i<=n;++i){
scanf("%lld",&z);
Insert(i,z);
}
Insert(n+1,1ll);
for(;m;--m){
scanf("%d%d%d",&op,&x,&y);
Splay(x,0);
Splay(y+2,x);
if(op==1){
scanf("%lld",&z);
mark(c[y+2][0],z);
}
else{
printf("%lld\n",totalval2[c[y+2][0]]);
}
}
return 0;
}
——The Solution By AutSky_JadeK From UESTC
转载请注明出处:http://www.cnblogs.com/autsky-jadek/

浙公网安备 33010602011771号
