社区讨论

85分答案错误求调(玄关)

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

讨论操作

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

当前回复
1 条
当前快照
1 份
快照标识符
@m0eyorob
此快照首次捕获于
2024/08/29 15:26
2 年前
此快照最后确认于
2025/11/04 22:06
4 个月前
查看原帖
关于答案贪心的逻辑是什么?
CPP
#include <bits/stdc++.h>
#define N 200005
#define INF 1145141919810
#define LL long long
#define ls (root << 1)
#define rs (root << 1 | 1)
using namespace std;

LL n,m,q,a[N],b[N],a_max,a_min,b_max,b_min,a_p,b_p,a_abs_max,a_abs_min,b_abs_max,b_abs_min;

struct tree
{
	LL Max,abs_Max,abs_Min,Min,p;
} tr1[N << 2], tr2[N << 2];

void build1(LL root,LL l,LL r)
{
	if(l == r)
	{
		if(a[l] > 0) tr1[root].Max = a[l],tr1[root].abs_Max = a[l];
		else tr1[root].abs_Max = 0;
		if(a[l] < 0) tr1[root].Min = a[l],tr1[root].abs_Min = a[l];
		else tr1[root].abs_Min = 0;
		if(a[l] == 0) tr1[root].p = 1,tr1[root].abs_Max = 0,tr1[root].abs_Min = 0;
		return;
	}
	LL mid = (l + r) >> 1;
	build1(ls,l,mid);
	build1(rs,mid + 1,r);
	tr1[root].Max = max(tr1[ls].Max , tr1[rs].Max);
	tr1[root].Min = min(tr1[ls].Min , tr1[rs].Min);
	tr1[root].abs_Max = min(tr1[ls].abs_Max , tr1[rs].abs_Max);
	tr1[root].abs_Min = max(tr1[ls].abs_Min , tr1[rs].abs_Min);
	tr1[root].p |= (tr1[ls].p | tr1[rs].p);
}


void build2(LL root,LL l,LL r)
{
	if(l == r)
	{
		if(b[l] > 0) tr2[root].Max = b[l],tr2[root].abs_Max = b[l];
		else tr2[root].abs_Max = 0;
		if(b[l] < 0) tr2[root].Min = b[l],tr2[root].abs_Min = b[l];
		else tr2[root].abs_Min = 0;
		if(b[l] == 0) tr1[root].p = 1,tr2[root].abs_Max = INF,tr2[root].abs_Min = 0;
		return;
	}
	LL mid = (l + r) >> 1;
	build2(ls,l,mid);
	build2(rs,mid + 1,r);
	tr2[root].Max = max(tr2[ls].Max , tr2[rs].Max);
	tr2[root].Min = min(tr2[ls].Min , tr2[rs].Min);
	tr2[root].abs_Max = min(tr2[ls].abs_Max , tr2[rs].abs_Max);
	tr2[root].abs_Min = max(tr2[ls].abs_Min , tr2[rs].abs_Min);
	tr2[root].p |= (tr2[ls].p | tr2[rs].p);
}

void query1(LL root,LL l,LL r,LL ql,LL qr)
{
	if(ql <= l && qr >= r)
	{
		a_max = max(a_max , tr1[root].Max);
		a_min = min(a_min , tr1[root].Min);
		a_p |= tr1[root].p;
		a_abs_max = min(a_abs_max , tr1[root].abs_Max);
		a_abs_min = max(a_abs_min , tr1[root].abs_Min);
		return;
	}
	int mid = (l + r) >> 1;
	if(ql <= mid) query1(ls,l,mid,ql,qr);
	if(qr > mid) query1(rs,mid + 1,r,ql,qr);
	return;
}

void query2(LL root,LL l,LL r,LL ql,LL qr)
{
	if(ql <= l && qr >= r)
	{
		b_max = max(b_max , tr2[root].Max);
		b_min = min(b_min , tr2[root].Min);
		b_p |= tr2[root].p;
		b_abs_max = min(b_abs_max , tr2[root].abs_Max);
		b_abs_min = max(b_abs_min , tr2[root].abs_Min);
		return;
	}
	int mid = (l + r) >> 1;
	if(ql <= mid) query2(ls,l,mid,ql,qr);
	if(qr > mid) query2(rs,mid + 1,r,ql,qr);
	return;
}

int main()
{
//	freopen("hack.in","r",stdin);
//	freopen("game.out","w",stdout);
	cin >> 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]);
	build1(1,1,n);
	build2(1,1,m);
	while(q--)
	{
		a_max = 0, a_min = 0, b_max = 0, b_min = 0,a_p = 0, b_p = 0,a_abs_max = INF,a_abs_min = -INF,b_abs_max = INF,b_abs_min = -INF;
		LL l1,r1,l2,r2;
		scanf("%lld%lld%lld%lld", &l1, &r1, &l2, &r2);
		query1(1ll,1ll,n,l1,r1);
		query2(1ll,1ll,m,l2,r2);
		if(b_min != 0 && b_max != 0)
		{
			if(a_p == 1) printf("0\n");
			else if(a_max != 0 && a_min != 0) printf("%lld\n", max(a_abs_max * b_min , a_abs_min * b_max));
			else if(a_max != 0) printf("%lld\n", a_abs_max * b_min);
			else printf("%lld\n", a_abs_min * b_max);
		}
		else if(b_min != 0)
		{
			if(b_p == 1 && a_min != 0) printf("0\n");
			else if(a_min != 0) printf("%lld\n", a_min * b_abs_min);
			else if(a_p == 1) printf("0\n");
			else printf("%lld\n", a_abs_max * b_min);
		}
		else if(b_max != 0)
		{
			if(b_p == 1 && a_max != 0) printf("0\n");
			else if(a_max != 0) printf("%lld\n", a_max * b_abs_max);
			else if(a_p == 1) printf("0\n");
			else printf("%lld\n", a_abs_min * b_max);
		}
		else printf("0\n");
	}
	return 0;
}

回复

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

正在加载回复...