分块爆零,球条,悬2关
  • 板块P1816 忠诚
  • 楼主YONEX
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/10/23 17:01
  • 上次更新2024/10/23 19:01:26
查看原帖
分块爆零,球条,悬2关
737219
YONEX楼主2024/10/23 17:01
#include<bits/stdc++.h>
#define ll long long 
//#define int long long
const ll maxn=1e9;
using namespace std;
ll k[100005];int m,n,p;ll a,b,c,ans=maxn;
ll add[100007],pos[100007]/*判断点属于哪一个块*/;
ll sum[100007],mix[100007];
int line_l[100007],line_r[100007];
inline long long read() 
{ 
	char cc=getchar();long long f=1,ans=0;
	while(cc<'0' or cc>'9'){if(cc=='-')f=-1;cc=getchar();} 
	while(cc>='0' and cc<='9'){ans=(ans*10)+(cc-'0');cc=getchar();} 
	return f*ans;
}  
inline void reads() 
{ 
	n=read();m=read();
	for(int i=1;i<=n;i++) k[i]=read();
}  
inline void build() 
{  
	int t=sqrt(n);//块的个数 
	for(int i=1;i<=t;i++){line_l[i]=(i-1)*t+1;line_r[i]=i*t;}//设置左右边界 
	if(line_r[t]<=n){t++;line_l[t]=line_r[t-1]+1;line_r[t]=n;}//特判最后一个块不完整 
	for(int i=1;i<=t;i++) 
	{ 
		for(int j=line_l[i];j<=line_r[i];j++){pos[j]=i;sum[i]+=k[j];} 
		for(int j=line_l[i];j<=line_r[i];j++){mix[i]=maxn;mix[i]=min(mix[i],k[j]);}  
	}//初始化区间加值和这个点属于那个块
} 
inline void ask_line()  
{  
	a=read();b=read();ans=maxn;
	if(pos[a]==pos[b]) 
	{ 
		for(int i=a;i<=b;i++)ans=min(k[i],ans);
//		ans+=add[pos[a]]*(b-a+1);
		printf("%lld",ans);cout<<" ";return ;
	}  
	for(int i=pos[a]+1;i<=pos[b]-1;i++){ans=min(mix[i],ans);} 
	for(int i=a;i<=line_r[pos[a]];i++){ans=min(k[i],ans);} 
	for(int i=line_l[pos[b]];i<=b;i++){ans=min(k[i],ans);} 
	printf("%lld",ans);cout<<" ";return ;
}  
inline void main_d() 
{ 
	reads();build();
	for(int i=1;i<=m;i++) {ans=0;ask_line();} 
}  
int main(){main_d();return 0;} 
2024/10/23 17:01
加载中...