线段树,求调
查看原帖
线段树,求调
101654
_Victor楼主2022/11/21 10:17
#include<bits/stdc++.h>
using namespace std;
int t,n,q;
long long s[1000005],top;
long long ans[1000005],a[1000005],b[1000005]; 
struct c{
	int o,l,r;
	long long x;
}d[1000005];
struct tree{
	int l,r;
	long long mi,la;
}f[5000005];
void build(int p,int l,int r)
{
	f[p].l=l,f[p].r=r,f[p].la=0;
	if(l==r)
	{
		f[p].mi=b[l];
		return;
	}
	int mid=l+r>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	f[p].mi=min(f[p<<1].mi,f[p<<1|1].mi);
}
void spread(int p)
{
	f[p<<1].mi-=f[p].la;
	f[p<<1].la+=f[p].la;
	f[p<<1|1].mi-=f[p].la;
	f[p<<1|1].la+=f[p].la;
	f[p].la=0; 
}
void change(int p,int l,int r,long long k)
{	
	if(f[p].l>=l&&f[p].r<=r)
	{
		f[p].mi-=k;
		f[p].la+=k;
		return;
	}	
	spread(p);
	int mid=f[p].l+f[p].r>>1;
	if(mid>=l)
		change(p<<1,l,r,k);
	if(mid<r)
		change(p<<1|1,l,r,k);
	f[p].mi=min(f[p<<1].mi,f[p<<1|1].mi);
}
long long ask(int p,int l,int r)
{
	spread(p);
	if(f[p].l>=l&&f[p].r<=r)
	{
		return f[p].mi;
	}
	long long an=0x7fffffff;
	int mid=f[p].l+f[p].r>>1;
	if(mid>=l)
		an=min(an,ask(p<<1,l,r));
	if(mid<r)
		an=min(an,ask(p<<1|1,l,r));
	return an;
}
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n>>q;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
		}
		for(int i=1;i<=q;i++)
		{
			cin>>d[i].o>>d[i].l>>d[i].r;
			if(d[i].o==1)
			{
				cin>>d[i].x;
			}
		}
		for(int i=1;i<=n;i++)
		{
			cin>>b[i];
		}
		build(1,1,n);
		for(int i=q;i>0;i--)
		{
			if(d[i].o==1)
			{
				change(1,d[i].l,d[i].r,d[i].x);
			}
			if(d[i].o==2)
			{
				s[top++]=ask(1,d[i].l,d[i].r);
			}
		}
		for(int i=top-1;i>=0;i--)
		{
			cout<<s[i]<<" ";
		}
		cout<<endl;
	}
    return 0;
}
2022/11/21 10:17
加载中...