线段树模板
单点更新,区间求最值
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define N 222222
using namespace std;
int num[N];
struct Tree
{
int l;
int r;
int max;
} tree[N*4];
void push_up(int root)
{
tree[root].max=max(tree[root<<1].max,tree[root<<1|1].max);
}
void build(int root,int l,int r)
{
tree[root].l=l;
tree[root].r=r;
if(tree[root].l==tree[root].r)
{
tree[root].max=num[l];
return;
}
int mid=(l+r)/2;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
push_up(root);
}
void update(int root,int pos,int val)
{
if(tree[root].l==tree[root].r)
{
tree[root].max=val;
return;
}
int mid=(tree[root].l+ tree[root].r)/2;
if(pos<=mid)
update(root<<1,pos,val);
else
update(root<<1|1,pos,val);
push_up(root);
}
int query(int root,int L,int R)
{
if(L<=tree[root].l&&R>=tree[root].r)
return tree[root].max;
int mid=(tree[root].l+ tree[root].r)/2,ret=0;
if(L<=mid) ret=max(ret,query(root<<1,L,R));
if(R>mid) ret=max(ret,query(root<<1|1,L,R));
return ret;
}
区间更新,区间求和
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define N 222222
using namespace std;
int num[N];
struct Tree
{
int l;
int r;
long long sum;
long long col;
} tree[N*4];
void push_up(int rt)
{
tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
}
void push_down(int rt,int m)
{
if (tree[rt].col!=0)
{
tree[rt<<1].col+=tree[rt].col;
tree[rt<<1|1].col+=tree[rt].col;
tree[rt<<1].sum+=(long long)(m-(m/2))*tree[rt].col;
tree[rt<<1|1].sum+=(long long)(m/2)*tree[rt].col;
tree[rt].col=0;
}
}
void build(int root,int l,int r)
{
tree[root].l=l;
tree[root].r=r;
tree[root].col=0;
if(tree[root].l==tree[root].r)
{
tree[root].sum=num[l];
return;
}
int mid=(l+r)/2;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
push_up(root);
}
void update(int root,int L,int R,int val)
{
if(L<=tree[root].l&&R>=tree[root].r)
{
tree[root].col+=val;
tree[root].sum+=(long long)val*(tree[root].r-tree[root].l+1);
return;
}
push_down(root,tree[root].r-tree[root].l+1);
int mid=(tree[root].l+tree[root].r)/2;
if (L<=mid)
update(root<<1,L,R,val);
if (R>mid)
update(root<<1|1,L,R,val);
push_up(root);
}
long long query(int root,int L,int R)
{
if(L<=tree[root].l&&R>=tree[root].r)
return tree[root].sum;
push_down(root,tree[root].r-tree[root].l+1);
int mid=(tree[root].l+ tree[root].r)/2;
long long ret=0;
if(L<=mid) ret+=query(root<<1,L,R);
if(R>mid) ret+=query(root<<1|1,L,R);
return ret;
}
成段更新,区间求值
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define N 555555
using namespace std;
const int OO=1e9;
int num[N];
int _min,_max,_sum;
struct Tree
{
int l;
int r;
int max;
int min;
int sum;
int add;
int set;
}big_tree[N*4];
void push_up(int root,Tree tree[])
{
tree[root].max=max(tree[root<<1].max,tree[root<<1|1].max);
tree[root].min=min(tree[root<<1].min,tree[root<<1|1].min);
tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
}
void push_down(int root,Tree tree[])
{
if (tree[root].set!=-1)
{
if (tree[root].l!=tree[root].r)
{
//传递懒惰标记
tree[root<<1].add=tree[root<<1|1].add=0;
tree[root<<1].set=tree[root<<1|1].set=tree[root].set;
//最更新大值
tree[root<<1].max=tree[root<<1|1].max=tree[root].set;
//更新最小值
tree[root<<1].min=tree[root<<1|1].min=tree[root].set;
//更新区间和
tree[root<<1].sum=(tree[root<<1].r-tree[root<<1].l+1)*tree[root].set;
tree[root<<1|1].sum=(tree[root<<1|1].r-tree[root<<1|1].l+1)*tree[root].set;
}
tree[root].set=-1;
}
if (tree[root].add>0)
{
if (tree[root].l!=tree[root].r)
{
//传递懒惰标记
tree[root<<1].add+=tree[root].add;
tree[root<<1|1].add+=tree[root].add;
//更新最大值
tree[root<<1].max+=tree[root].add;
tree[root<<1|1].max+=tree[root].add;
//更新最小值
tree[root<<1].min+=tree[root].add;
tree[root<<1|1].min+=tree[root].add;
//更新区间和
tree[root<<1].sum+=(tree[root<<1].r-tree[root<<1].l+1)*tree[root].add;
tree[root<<1|1].sum+=(tree[root<<1|1].r-tree[root<<1|1].l+1)*tree[root].add;
}
tree[root].add=0;
}
}
void build(int root,int l,int r,Tree tree[])
{
tree[root].l=l;
tree[root].r=r;
if(tree[root].l==tree[root].r)
{
tree[root].max=0;
tree[root].min=0;
tree[root].sum=0;
tree[root].add=0;
tree[root].set=-1;
return;
}
int mid=(l+r)/2;
build(root<<1,l,mid,tree);
build(root<<1|1,mid+1,r,tree);
push_up(root,tree);
}
void update_add(int root,int L,int R,int val,Tree tree[])
{
if(L<=tree[root].l&&R>=tree[root].r)
{
tree[root].add+=val;
tree[root].max+=val;
tree[root].min+=val;
tree[root].sum+=(tree[root].r-tree[root].l+1)*val;
return;
}
push_down(root,tree);
int mid=(tree[root].l+tree[root].r)/2;
if(L<=mid)
update_add(root<<1,L,R,val,tree);
if (R>mid)
update_add(root<<1|1,L,R,val,tree);
push_up(root,tree);
}
void update_set(int root,int L,int R,int val,Tree tree[])
{
if(L<=tree[root].l&&R>=tree[root].r)
{
tree[root].set=val;
tree[root].add=0;
tree[root].max=val;
tree[root].min=val;
tree[root].sum=(tree[root].r-tree[root].l+1)*val;
return;
}
push_down(root,tree);
int mid=(tree[root].l+tree[root].r)/2;
if(L<=mid)
update_set(root<<1,L,R,val,tree);
if (R>mid)
update_set(root<<1|1,L,R,val,tree);
push_up(root,tree);
}
void query(int root,int L,int R,Tree tree[])
{
if(L<=tree[root].l&&R>=tree[root].r)
{
_min=min(_min,tree[root].min);
_max=max(_max,tree[root].max);
_sum+=tree[root].sum;
return;
}
push_down(root,tree);
int mid=(tree[root].l+tree[root].r)/2;
if(L<=mid) query(root<<1,L,R,tree);
if(R>mid) query(root<<1|1,L,R,tree);
}
浙公网安备 33010602011771号