社区讨论

两个线段树 90pts求调

P8818[CSP-S 2022] 策略游戏参与者 5已保存回复 6

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
6 条
当前快照
1 份
快照标识符
@lo7nyv0t
此快照首次捕获于
2023/10/27 04:55
2 年前
此快照最后确认于
2023/10/27 04:55
2 年前
查看原帖
C
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int mod=1e9+7;
typedef long long ll;
inline int read()
{
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9')
	{
		if(c=='-')
			f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		x=(x*10)+(c-'0');
		c=getchar();
	}
	return x*f;
}
int a[maxn],b[maxn];
struct segment
{
	int l,r;
	ll zmx=0,zmn=INT_MAX,fmx=0,fmn=INT_MIN;
	int ze=0;
}c[maxn<<2],d[maxn<<2];
void abuild(int x,int l,int r)
{
	c[x].l=l;c[x].r=r;
	if(l==r)
	{
		if(a[l]<0)
			c[x].fmx=c[x].fmn=a[l];
		else if(a[l]>0)
			c[x].zmx=c[x].zmn=a[l];
		else
			c[x].ze=1;
		return;
	}
	int mid=(l+r)>>1;
	abuild(x<<1,l,mid);
	abuild(x<<1|1,mid+1,r);
	c[x].zmx=max(c[x<<1].zmx,c[x<<1|1].zmx);
	c[x].fmx=min(c[x<<1].fmx,c[x<<1|1].fmx);
	c[x].zmn=min(c[x<<1].zmn,c[x<<1|1].zmn);
	c[x].fmn=max(c[x<<1].fmn,c[x<<1|1].fmn);
	c[x].ze=c[x<<1].ze|c[x<<1|1].ze;
	return;
}
void pushup(segment &ans,segment t)
{
	ans.zmx=max(ans.zmx,t.zmx);
	ans.fmx=min(ans.fmx,t.fmx);
	ans.zmn=min(ans.zmn,t.zmn);
	ans.fmn=max(ans.fmn,t.fmn);
	ans.ze=ans.ze|t.ze;
	return;
}
segment aquery(int x,int l,int r)
{
	if(c[x].l>=l&&c[x].r<=r)
		return c[x];
	int mid=(c[x].l+c[x].r)>>1;
	segment ans;
	if(mid>=l)
		pushup(ans,aquery(x<<1,l,r));
	if(mid+1<=r)
		pushup(ans,aquery(x<<1|1,l,r));
	return ans;
}
void bbuild(int x,int l,int r)
{
	d[x].l=l;d[x].r=r;
	if(l==r)
	{
		if(b[l]<0)
			d[x].fmx=d[x].fmn=b[l];
		else if(b[l]>0)
			d[x].zmx=d[x].zmn=b[l];
		else
			d[x].ze=1;
		return;
	}
	int mid=(l+r)>>1;
	bbuild(x<<1,l,mid);
	bbuild(x<<1|1,mid+1,r);
	d[x].zmx=max(d[x<<1].zmx,d[x<<1|1].zmx);
	d[x].fmx=min(d[x<<1].fmx,d[x<<1|1].fmx);
	d[x].zmn=min(d[x<<1].zmn,d[x<<1|1].zmn);
	d[x].fmn=max(d[x<<1].fmn,d[x<<1|1].fmn);
	d[x].ze=d[x<<1].ze|d[x<<1|1].ze;
	return;
}
segment bquery(int x,int l,int r)
{
	if(d[x].l>=l&&d[x].r<=r)
		return d[x];
	int mid=(d[x].l+d[x].r)>>1;
	segment ans;
	if(mid>=l)
		pushup(ans,bquery(x<<1,l,r));
	if(mid+1<=r)
		pushup(ans,bquery(x<<1|1,l,r));
	return ans;
}
int main()
{
	int n,m,q;
	n=read(),m=read(),q=read();
	for(int i=1;i<=n;i++)
		a[i]=read();
	for(int i=1;i<=m;i++)
		b[i]=read();
	abuild(1,1,n);
	bbuild(1,1,m);
	int la,ra,lb,rb;
	segment t,g;
	for(int i=1;i<=q;i++)
	{
		la=read(),ra=read(),lb=read(),rb=read();
		t=aquery(1,la,ra);
		g=bquery(1,lb,rb);
		if(g.fmn!=INT_MIN&&g.zmn!=INT_MAX)
		{
			if(t.ze==1)
				printf("0\n");
			else if(1ll*t.zmn*g.fmx>1ll*t.fmn*g.zmx)
				printf("%lld\n",1ll*t.zmn*g.fmx);
			else
				printf("%lld\n",1ll*t.fmn*g.zmx);
		}
		else if(g.fmn==INT_MIN)
		{
			if(g.ze==1&&t.zmx!=0)
				printf("0\n");
			else if(t.zmx!=0)
				printf("%lld\n",1ll*t.zmx*g.zmn);
			else
				printf("%lld\n",1ll*t.fmn*g.zmx);
		}
		else if(g.zmn==INT_MAX)
		{
			if(g.ze==1&&t.fmx!=0)
				printf("0\n");
			else if(t.fmx!=0)			
				printf("%lld\n",1ll*t.fmx*g.fmn);
			else
				printf("%lld\n",1ll*t.zmn*g.fmx);
		}
		else
			printf("ERR\n");
	}
	return 0;
}
考场代码,自认为没问题但还是挂了TAT
退役了。

回复

6 条回复,欢迎继续交流。

正在加载回复...