CF1440E Greedy Shopping - Line segment tree

Portal

Title

Give you an array that does not rise initially, two kinds of queries:

  1. 1 xy: assign each ai of 1≤i≤x to max(ai,y);
  2. 2 xy: traverse from x to n, if ai ≤ y, then y subtract ai, make a contribution, and then traverse down. Output the final contribution sum.

answer

Obviously, after each 1 operation, the array still does not rise, and a breakpoint i ≤ x must be found, the number before i remains unchanged, and the numbers after it all become y.

Then the segment tree can be established, the first two points O(log_{2}n)to find a breakpoint, then O(log_{2}n)the i + 1 ~ x assigned to Y;

For the 2 operation, the violent idea should be to find an interval (l, r), the sum of the interval just does not exceed y, and then subtract the interval sum from y, and then find the first point whose value does not exceed y from r+1, and then Extends to an interval and an interval that just does not exceed y...

Because of the line segment tree, the complexity of finding the interval and the complexity of finding the point are both equal O(log_{2}n), and the remaining trouble to us is how many times y will be subtracted.

Interval and is set s, apparently a_{r}s, since sjust not exceeded Y , there is  s+a_{r+1}>yand a_{r+1}a_{r}, can be obtained s>y/2, that is, each  Y at least by half, so reducing the number of times is not exceeded O(log_{2}y),

Total complexityO (nlog_ {2} nlog_ {2} y)

I was too anxious, looking at the title, thinking that it was a waste of time to allow a certain interval to be modified.······

Code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
#define MAXN 200005
using namespace std;
inline ll read(){
	ll x=0;bool f=1;char s=getchar();
	while((s<'0'||s>'9')&&s>0){if(s=='-')f^=1;s=getchar();}
	while(s>='0'&&s<='9')x=(x<<1)+(x<<3)+s-'0',s=getchar();
	return f?x:-x;
}
int n,q,N;
ll a[MAXN],f[MAXN<<2],lz[MAXN<<2],rt[MAXN<<2];
struct node{
	int x;ll y;
	node(){}
	node(int X,ll Y){x=X,y=Y;}
};
inline void build(int x,int l,int r){
	if(l==r){f[x]=rt[x]=a[l],lz[x]=0;return;}
	int mid=(l+r)>>1;
	build(x<<1,l,mid),build(x<<1|1,mid+1,r);
	f[x]=f[x<<1]+f[x<<1|1],rt[x]=rt[x<<1|1],lz[x]=0;
}
inline void pushdown(int x,int l,int r){
	if(lz[x]>0){
		int mid=(l+r)>>1;
		if(l<r)lz[x<<1]=lz[x<<1|1]=rt[x<<1]=rt[x<<1|1]=lz[x],f[x<<1]=lz[x]*(mid-l+1),f[x<<1|1]=lz[x]*(r-mid);
		lz[x]=0;
	}
}
inline void change(int x,int l,int r,int a,int b,ll w){
	if(a>b)return;
	if(l==a&&r==b){lz[x]=rt[x]=w,f[x]=w*(r-l+1);return;}
	pushdown(x,l,r);
	int mid=(l+r)>>1;
	if(a<=mid)change(x<<1,l,mid,a,min(mid,b),w);
	if(b>mid)change(x<<1|1,mid+1,r,max(a,mid+1),b,w);
	f[x]=f[x<<1]+f[x<<1|1],rt[x]=rt[x<<1|1];
}
inline int findc(int x,int l,int r,int a,int b,ll w){//找点
	if(l==r){
		if(f[x]<=w)return l;
		else return r+1;
	}
	pushdown(x,l,r);
	int mid=(l+r)>>1;
	if(l==a&&r==b){
		if(rt[x<<1]<=w)return findc(x<<1,l,mid,l,mid,w);
		else return findc(x<<1|1,mid+1,r,mid+1,r,w);
	}
	if(a<=mid){
		int u=findc(x<<1,l,mid,a,min(mid,b),w);
		if(u>min(mid,b)&&b>mid)return findc(x<<1|1,mid+1,r,max(a,mid+1),b,w);
		else return u;
	}
	else return findc(x<<1|1,mid+1,r,a,b,w);
}
inline node findd(int x,int l,int r,int a,int b,ll s){//找区间
	if(l==a&&r==b&&f[x]<=s)return node(b,f[x]);
	if(l==r)return node(l-1,0);
	pushdown(x,l,r);
	int mid=(l+r)>>1;
	node u=node(l-1,0),v=node(mid,0);
	if(a<=mid){
		u=findd(x<<1,l,mid,a,min(mid,b),s);
		if(b>mid&&u.x==mid)v=findd(x<<1|1,mid+1,r,mid+1,b,s-u.y);
		if(u.x==mid)return node(v.x,u.y+v.y);
		else return u;
	}
	else return findd(x<<1|1,mid+1,r,a,b,s);
}
int main()
{
	n=read(),q=read(),N=sqrt(n);
	for(int i=1;i<=n;i++)a[i]=read();
	build(1,1,n);
	while(q--){
		int opt=read(),x=read();ll y=read();
		if(opt==1){
			int o=findc(1,1,n,1,x,y);
			change(1,1,n,o,x,y);
		}
		else{
			int ans=0;
			for(int i=x;i<=n;i++){
				node o=findd(1,1,n,i,n,y);
				if(o.x>=i)ans+=o.x-i+1,y-=o.y,i=o.x;
				else i=findc(1,1,n,i,n,y)-1;
			}
			printf("%d\n",ans);
		}
	}
	return 0;
}

 

Guess you like

Origin blog.csdn.net/weixin_43960287/article/details/109865395