E. Greedy Shopping

E. Greedy Shopping_第1张图片

线段树经典题

维护最大值和最小值 还有区间和

#include
using namespace std;
using ll = long long;
const int N = 2e5+10;
ll w[N];
struct Segment{
	ll l,r;
	ll val,fmin,fmax;
	ll lz;
}tr[N<<2];

int n,m;



void pushup(int u){
	tr[u].val = tr[u<<1].val + tr[u<<1|1].val;
	tr[u].fmin = min(tr[u<<1].fmin,tr[u<<1|1].fmin);
	tr[u].fmax = max(tr[u<<1].fmax,tr[u<<1|1].fmax);
}

void build(int u,int l,int r){
	tr[u] = {l,r,0,0,0,0};
	if(l==r){tr[u] = {l,r,w[l],w[l],w[l],0};return;}
	int mid = l+r>>1;
	build(u<<1,l,mid),build(u<<1|1,mid+1,r);
	pushup(u);
}



void pushdown(Segment &node,int lz){
	node.lz = lz;
	node.val = (node.r-node.l+1)*lz;
	node.fmin = node.fmax = lz;
}

void pushdown(int u){
	if(tr[u].lz){
		pushdown(tr[u<<1],tr[u].lz);
		pushdown(tr[u<<1|1],tr[u].lz);
		tr[u].lz = 0;
	}
}

void modify(int u,int l,int r,int c){
	if(tr[u].l>=l&&tr[u].r<=r){
		if(tr[u].fmin>=c)return;
		if(tr[u].fmax>1;
	if(l<=mid)modify(u<<1,l,r,c);
	if(r>mid)modify(u<<1|1,l,r,c);
	
	pushup(u);

}

ll query(int u,int l,int r,ll &have){
	if(tr[u].l>=l&&tr[u].r<=r){
		if(have=tr[u].val){have-=tr[u].val;return tr[u].r-tr[u].l+1;}
		
	}
	
	pushdown(u);
	ll res = 0;
	int mid = tr[u].l+tr[u].r>>1;
	if(l<=mid)res+=query(u<<1,l,r,have);
	if(r>mid)res+=query(u<<1|1,l,r,have);
	return res;
	
}



int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>w[i];
	build(1,1,n);
	
	
	for(int i=1;i<=m;i++){
		ll op,l,r;cin>>op>>l>>r;
		if(op==1)modify(1,1,l,r);
		else cout<

你可能感兴趣的:(线段树,数据结构,算法)