社区讨论

民间数据挂一个点 #19,求助

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

讨论操作

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

当前回复
5 条
当前快照
1 份
快照标识符
@lo7hm3k9
此快照首次捕获于
2023/10/27 01:57
2 年前
此快照最后确认于
2023/10/27 01:57
2 年前
查看原帖
分类讨论九种情况,代码如下:
CPP
#include<bits/stdc++.h>
using namespace std;

namespace _
{
	typedef long long ll;
	const ll N=250000+10,inf=10000000001,L=17;
	ll LOG[N];
	struct RMQ
	{
		ll mn[L+3][N],mx[L+3][N];
		void init(const ll n,const ll d[])
		{
			for(ll i=1;i<=n;i++)
				mn[0][i]=mx[0][i]=d[i];
			for(ll i=1;i<=L;i++)
			{
				for(ll j=1;j<=n;j++)
				{
					mn[i][j]=min(mn[i-1][j],mn[i-1][j+(1ll<<(i-1))]);
					mx[i][j]=max(mx[i-1][j],mx[i-1][j+(1ll<<(i-1))]);
				}
			}
		}
		ll Max(ll l,ll r)
		{
			ll len=LOG[r-l+1];
			return max(mx[len][l],mx[len][r-(1ll<<len)+1]);
		}
		ll Min(ll l,ll r)
		{
			ll len=LOG[r-l+1];
			return min(mn[len][l],mn[len][r-(1ll<<len)+1]);
		}
	}A,B,Ap,An;
	ll n,m,q,a[N],b[N],c[N];
	ll type(ll l1,ll r1,ll l2,ll r2)
	{
		ll mx,mn;
		mx=A.Max(l1,r1);
		mn=A.Min(l1,r1);
		if(mx>=0&&mn>=0)//a>=0
		{
			mx=B.Max(l2,r2);
			mn=B.Min(l2,r2);
			if(mx>=0&&mn>=0) return 1;
			else if(mx<0&&mn<0) return 2;
			else return 7;
		}
		else if(mx<0&&mn<0)//a<0
		{
			mx=B.Max(l2,r2);
			mn=B.Min(l2,r2);
			if(mx>=0&&mn>=0) return 3;
			else if(mx<0&&mn<0) return 4;
			else return 8;
		}
		else //a
		{
			mx=B.Max(l2,r2);
			mn=B.Min(l2,r2);
			if(mx>=0&&mn>=0) return 5;
			else if(mx<0&&mn<0) return 6;
			else return 9;
		}
	}
	void main()
	{
		ll l1,r1,l2,r2,tmp;
		scanf("%lld%lld%lld",&n,&m,&q);
		for(ll i=1;i<=n;i++)
			scanf("%lld",a+i);
		for(ll i=1;i<=m;i++)
			scanf("%lld",b+i);
		for(ll i=1;i<=L;i++)
			LOG[(1ll<<i)]=1;
		for(ll i=1;i<=n;i++) LOG[i]+=LOG[i-1];
		A.init(n,a);
		B.init(m,b);
		for(ll i=1;i<=n;i++)
		{
			if(a[i]>=0) c[i]=-inf;
			else c[i]=a[i];
		}
		An.init(n,c);
		for(ll i=1;i<=n;i++)
		{
			if(a[i]<0) c[i]=inf;
			else c[i]=a[i];
		}
		Ap.init(n,c);
		for(ll i=1;i<=q;i++)
		{
			scanf("%lld%lld%lld%lld",&l1,&r1,&l2,&r2);
			tmp=type(l1,r1,l2,r2);
			if(tmp==1||tmp==5)
				printf("%lld\n",A.Max(l1,r1)*B.Min(l2,r2));
			else if(tmp==2||tmp==7)
				printf("%lld\n",A.Min(l1,r1)*B.Min(l2,r2));
			else if(tmp==3||tmp==8)
				printf("%lld\n",A.Max(l1,r1)*B.Max(l2,r2));
			else if(tmp==4||tmp==6)
				printf("%lld\n",A.Min(l1,r1)*B.Max(l2,r2));
			else
			{
				ll t1=An.Max(l1,r1)*B.Max(l2,r2);
				ll t2=Ap.Min(l1,r1)*B.Min(l2,r2);
				printf("%lld\n",max(t1,t2));
			}
		}
		return;
	}
}
int main()
{
	//freopen("game4.in","r",stdin);
	//freopen("game4.out","w",stdout);
	_::main();
	//system("fc game4.out game4.ans");
	return 0;
}

回复

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

正在加载回复...