线段树模版主要是由Build函数,Query函数,updata函数,pushdown函数组成
//Build函数
void Build(int id,int ll,int rr){
lazy[id]=0; //lazy数组的作用是存放区间变化的值,在单点更新的时候可以忽略
if(ll==rr){
s[id]=1;
return;
}
int mid=(ll+rr)/2;
Build(id*2,ll,mid);
Build(id*2+1,mid+1,rr);
s[id]=s[id*2]+s[id*2+1]; //这个地方随着题目的要求而变化
}
//数据的更新
void updata(int id,int ll,int rr,int l,int r,int v){
if(l<=ll&rr<=r){
lazy[id]=v; // 单点更新忽略
s[id]=(rr-ll+1)*v;
return;
}
if(lazy[id])
pushdown(id,ll,rr); // 单点更新忽略
int mid=(ll+rr)/2;
if(r<=mid) // 当查询的右值在中点的左边就只查询左边到中间
updata(id*2,ll,mid,l,r,v);
else if(l>mid) // 同上
updata(id*2+1,mid+1,rr,l,r,v);
else{ //两个都不是的话就要更新左右两边
updata(id*2,ll,mid,l,r,v);
updata(id*2+1,mid+1,rr,l,r,v);
}
s[id]=s[id*2]+s[id*2+1]; //每次都把数据更新了(很重要)
}
//pushdown函数是在区间更新的时候用到的
//作用就是把lazy里面的数据下放到接下来的两个数据
// 基本上都能直接用
void pushdown(int id,int l,int r){
int mid=(l+r)/2;
int ls=id*2,rs=id*2+1;
lazy[ls]=lazy[rs]=lazy[id];
s[ls]=(mid-l+1)*lazy[ls];
s[rs]=(r-mid)*lazy[rs];
lazy[id]=0;
}
我就直接把HDU - 1698 Just a Hook的代码贴在这儿
#include<bits/stdc++.h>
using namespace std;
int s[400005],lazy[400005];
void pushdown(int id,int l,int r){
int mid=(l+r)/2;
int ls=id*2,rs=id*2+1;
lazy[ls]=lazy[rs]=lazy[id];
s[ls]=(mid-l+1)*lazy[ls];
s[rs]=(r-mid)*lazy[rs];
lazy[id]=0;
}
void build(int id,int ll,int rr){
lazy[id]=0;
if(ll==rr){
s[id]=1;
return;
}
int mid=(ll+rr)/2;
build(id*2,ll,mid);
build(id*2+1,mid+1,rr);
s[id]=s[id*2]+s[id*2+1];
}
void updata(int id,int ll,int rr,int l,int r,int v){
if(l<=ll&rr<=r){
lazy[id]=v;
s[id]=(rr-ll+1)*v;
return;
}
if(lazy[id])
pushdown(id,ll,rr);
int mid=(ll+rr)/2;
if(r<=mid)
updata(id*2,ll,mid,l,r,v);
else if(l>mid)
updata(id*2+1,mid+1,rr,l,r,v);
else{
updata(id*2,ll,mid,l,r,v);
updata(id*2+1,mid+1,rr,l,r,v);
}
s[id]=s[id*2]+s[id*2+1];
}
int main(){
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++){
int n,m;
scanf("%d%d",&n,&m);
build(1,1,n);
while(m--){
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
updata(1,1,n,l,r,x);
}
printf("Case %d: The total value of the hook is %d.\n",i,s[1]);
}
return 0;
}