I love max and multiply HDU - 6971(详细解答)

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了I love max and multiply HDU - 6971(详细解答)相关的知识,希望对你有一定的参考价值。

I love max and multiply HDU - 6971

题意:

数组a和b,现在构造一个数组c,使得c[k]=max(a[i] * b[j]) , i&j>=k
求数组c的和

题解:

我们可以考虑求出所有Dk=max(Ai * Bj)并满足i&j=k,然后再从后向前取,但是i&j=k不好求,那就改成Dk=max(Ai * Bj),满足k∈i&j
k∈i&j,我们可以分别求k∈i和k∈j的情况
就比如:
k = 1010,k∈i&j,
i&j可以是:
1010
1011
1110
1111
那么我们就让i和j分别取这几个值求最大值,因为题目中存在负数,负数乘负数可能值更大,所以我们同时记录Ai和Bj的最大值和最小值
在代码实现中,当我们循环到1010,我们就将其值赋给其子集,这样就实现了k属于i&j
最后记得从后向前取最大(为什么还要这步呢?就比如k=1010,我们当前得到的最大值是1010所属于的集合,但是有些集合大于k但是k不属于,如果i<j,那么j的集合一定大于i,所以j的集合也是满足i的条件的,反之不一定,所以倒着赋值)

代码:

#include<bits/stdc++.h> 
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;

const int N=1000010,mod=998244353,INF=0x3f3f3f3f;
const double eps=1e-6;

int n;
int a[N],b[N];
LL mx1[N],mx2[N],mi1[N],mi2[N],c[N];
void solve(){
	scanf("%d",&n);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	for(int i=0;i<n;i++) scanf("%d",&b[i]);
	
	int all=(int)log2(n)+1;
	for(int i=0;i<1<<all;i++) {
		mx1[i]=mx2[i]=-INF;
		mi1[i]=mi2[i]=INF;
		c[i]=-1e18;
	}
	for(int i=0;i<n;i++) mx1[i]=mi1[i]=a[i];
	for(int i=0;i<n;i++) mx2[i]=mi2[i]=b[i];
	
	for(int i=0;i<all;i++) {
		for(int j=0;j<1<<all;j++) {
			if(j>>i&1) {
				mx1[j^(1<<i)]=max(mx1[j^(1<<i)],mx1[j]);
			}
		}
	}
	
	for(int i=0;i<all;i++) {
		for(int j=0;j<1<<all;j++) {
			if(j>>i&1) {
				mi1[j^(1<<i)]=min(mx1[j^(1<<i)],mx1[j]);
			}
		}
	}
	
	for(int i=0;i<all;i++) {
		for(int j=0;j<1<<all;j++) {
			if(j>>i&1) {
				mx2[j^(1<<i)]=max(mx2[j^(1<<i)],mx2[j]);
			}
		}
	}
	
	for(int i=0;i<all;i++) {
		for(int j=0;j<1<<all;j++) {
			if(j>>i&1) {
				mi2[j^(1<<i)]=min(mi2[j^(1<<i)],mi2[j]);
			}
		}
	}
	
	LL now=1ll*INF*INF;
	for(int i=0;i<n;i++) {
		if(mx1[i]!=INF&&mx2[i]!=INF) c[i]=max(c[i],mx1[i]*mx2[i]);
		if(mi1[i]!=-INF&&mi2[i]!=-INF) c[i]=max(c[i],mi1[i]*mi2[i]); 
		if(mx1[i]!=INF&&mi2[i]!=-INF) c[i]=max(c[i],mx1[i]*mi2[i]);
		if(mi1[i]!=-INF&&mx2[i]!=INF) c[i]=max(c[i],mi1[i]*mx2[i]);
	}
	
	for(int i=n-2;i>=0;i--) c[i]=max(c[i],c[i+1]);
	
	LL ans=0;
	for(int i=0;i<n;i++) ans+=c[i]%mod,ans+=mod,ans%=mod;
	printf("%lld\\n",ans);
}
int main()
{
	int T; scanf("%d",&T);
	while(T--) 
	{
		solve();	
	}
	return 0;
}

以上是关于I love max and multiply HDU - 6971(详细解答)的主要内容,如果未能解决你的问题,请参考以下文章

Someone You Love 歌词

Codeforces 573B Bear and Blocks

流水灯--“I LOVE YOU”

UVA10679 I Love Strings!!字符串匹配

c语言编译时one or more multiply defined symbols found 。刚学c求大侠帮忙看看

CodeForces - 1609A Divide and Multiply