线段数可以解决的问题:区间最大值或最小值,区间修改求和
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson k<<1
#define rson (k<<1)+1
const int N=2e5+5;
struct node{
int l,r,w,f;//f为树懒标记
}s[N<<2];//一般开点的4倍
void build(int k,int ll,int rr)
{
s[k].l=ll,s[k].r=rr;
if(s[k].l==s[k].r)
{
s[k].w=1;
// scanf("%d",&s[k].w);
return ;
}
int m=(ll+rr)>>1;
build(lson,ll,m);
build(rson,m+1,rr);
s[k].w=(s[lson].w+s[rson].w);
}
void down(int k)//区间修改多次询问,树懒标记
{
s[lson].f=s[k].f;
s[rson].f=s[k].f;
s[lson].w=(s[lson].r-s[lson].l+1)*s[k].f;
s[rson].w=(s[rson].r-s[rson].l+1)*s[k].f;
s[k].f=0;
}
void ask(int k)
{
if(s[k].l==s[k].r)
{
ans+=s[k].w;
return ;
}
if(s[k].f)
down(k);
int m=(s[k].l+s[k].r)>>1;
if(a<=m)//a为询问的左端点
ask(lson);
if(b>m)//b为询问的右端点
ask(rson);
}
void change(int k)
{
if(s[k].l>=a&&s[k].r<=b)
{
s[k].w=(s[k].r-s[k].l+1)*y;//y为修改的值
s[k].f=y;
return ;
}
if(s[k].f)
down(k);
int m=(s[k].l+s[k].r)>>1;
if(a<=m)
change(lson);
if(b>m)
change(rson);
s[k].w=(s[lson].w+s[rson].w);
}