题目:https://acm.hdu.edu.cn/showproblem.php?pid=6971
题意:给一个A数组和一个B数组,求出一个C数组,求的方式是,C数组的下标k,A、B数组的下标分别是i、j, Ck=max{Ai*Bj} 并且还要满 足(i&j≥k)
代码:
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
//#include <unordered_map>
//#include <unordered_set>
//#include <bits/stdc++.h>
//#define int long long
#define pb push_back
#define PII pair<int, int>
#define mpr make_pair
#define ms(a, b) memset((a), (b), sizeof(a))
#define x first
#define y second
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int N = 1e6 + 7;
const int mod = 998244353;
using namespace std;
int A[N], B[N], a[N], b[N];
signed main(int argc, char const *argv[]) {
int T;
scanf("%d", &T);
while (T--) {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
A[i] = a[i];
}
for (int i = 0; i < n; i++) {
scanf("%d",&b[i]);
B[i]=b[i];
}
int m = 1;
while (m < n) m <<= 1; //找到最高位数
for (int i = n; i < m; i++) {//b到最高位数小一直接的所有数进行初始化
A[i] = B[i] = -inf; //因为下面异或可能访问到这里
a[i] = b[i] = inf;
}
for (int i = 1; i < m; i <<= 1) { //枚举每一位
for (int j = n - 1; j >= 0; j--) {
if (!(i & j)) { //如果i的这一位不存在,就去异或找存在的那一位,求最大或最小
A[j] = max(A[j], A[i ^ j]);
B[j] = max(B[j], B[i ^ j]);
a[j] = min(a[j], a[i ^ j]);
b[j] = min(b[j], b[i ^ j]);
}
}
}
ll maxx = -INF;
ll s = 0; //找出最大值,如果比i大的那些下标的maxx更大,我这个i应该选那个更优
for (int i = n - 1; i >= 0; i--) {
maxx = max(maxx, (ll)A[i] * B[i]);
maxx = max(maxx, (ll)a[i] * b[i]);
maxx = max(maxx, (ll)a[i] * B[i]);
maxx = max(maxx, (ll)A[i] * b[i]);
s = (s + (maxx) % mod) % mod;
}
s = (s + mod) % mod;
printf("%lld\n", s);
}
return 0;
}