线段树区间最小值求助
  • 板块灌水区
  • 楼主ChenZQ
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/3/19 18:49
  • 上次更新2024/3/19 20:38:39
查看原帖
线段树区间最小值求助
745358
ChenZQ楼主2024/3/19 18:49

#include <bits/stdc++.h>
using namespace std;

const int N = 800010;
int seg[N],tag[N],a[100010];
int n;

void pushdown(int u)
{
	seg[u*2]+=tag[u];seg[u*2+1]+=tag[u];
	tag[u*2]+=tag[u];tag[u*2+1]+=tag[u];
	tag[u]=0;
}
void build_tree(int l,int r,int u)
{
	if(l==r) 
	{
		seg[u]=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build_tree(l,mid,u*2);build_tree(mid+1,r,u*2+1);
	seg[u]=min(seg[u*2],seg[u*2+1]);
}
string s;
int aa,b,c;
int ask(int l,int r,int u)
{
	if(l>=aa && r<=b) return seg[u];
	int mid=(l+r)>>1;
	int mi=11451419;
	pushdown(u);
	if(mid>=aa && l<=b) mi=min(mi,ask(l,mid,u*2));
	if(r>=aa && mid+1<=b) mi=min(mi,ask(mid+1,r,u*2+1));
	return mi; 
}
void add(int l,int r,int u)
{
	//cout<<l<<" "<<r<<endl;
	if(l>r) return;
	
	if(l>=aa && r<=b)
	{
		seg[u]+=c;
		tag[u]+=c;
		return;
	}
	if(l==r) return;
	pushdown(u);
	int mid=(l+r)/2;
	add(l,mid,u*2);
	add(mid+1,r,u*2+1);
	seg[u]=min(seg[u*2],seg[u*2+1]);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	build_tree(1,n,1);
	int m;
	scanf("%d",&m);getline(cin,s);
	while(m--)
	{
		getline(cin,s);
		//cout<<s<<" "<<s.size()<<endl;
		int t=s.size();
		int j=0;
		while(j<t && isdigit(s[j])) aa=aa*10+s[j]-'0',j++;
		j++;
		while(j<t && isdigit(s[j])) b=b*10+s[j]-'0',j++;
		aa++,b++;
		if(j+2>t)
		{
			//cout<<aa<<" "<<b<<endl;
			//cout<<"using:";
			printf("%d\n",ask(1,n,1));
		}
		else
		{
			
			j++;
			int flag=0;
			while((s[j]=='-' || isdigit(s[j])) && j<t)
			{
				if(s[j]=='-') flag=-1;
				else c=c*10+s[j]-'0';
				j++;
			}
			if(flag!=0) c*=flag;
			//cout<<aa<<" "<<b<<" "<<c<<endl;
			add(1,n,1);
		}
		aa=0,b=0,c=0;
	}
}

莫名其妙超时

2024/3/19 18:49
加载中...