B. Cobb
题目传送门:
题面:
题目大意:
意思就是说找出一个值在数组中的最大情况,对于这个值的定义求法用到的是数对 i , j {i,j} i,j:
- i ∗ j − k ∗ ( a i ∣ a j ) i*j-k*(a_i|a_j) i∗j−k∗(ai∣aj);
- 1 ≤ i , j ≤ n 1≤i,j≤n 1≤i,j≤n;
思路:
观察
i
∗
j
−
k
∗
(
a
i
∣
a
j
)
i*j-k*(a_i|a_j)
i∗j−k∗(ai∣aj),要让它取最大值,
i
∗
j
i*j
i∗j需要尽可能大。
所以思路是从大往小遍历。
条件break;
if (ans > i * (i - 1))
break;
//跳出整个i的循环if (ans >= i * j) break;
//遍历到下一个i
听到有大哥说其实从后往前遍历100组就差不多了,哎我不会算,之后去问问,学会了再补充到这里。
好像找到了,加一手官方题解:
当
a
i
=
a
n
=
0
a_i=a_n=0
ai=an=0时:
f
(
i
,
n
)
=
i
∗
n
−
k
∗
0
=
i
∗
n
f(i,n)=i*n-k*0=i*n
f(i,n)=i∗n−k∗0=i∗n
已知
a
i
∣
a
j
≤
2
n
a_i|a_j≤2n
ai∣aj≤2n:
f
(
n
−
1
,
n
)
=
(
n
−
1
)
∗
n
−
k
∗
2
n
f(n-1,n)=(n-1)*n-k*2n
f(n−1,n)=(n−1)∗n−k∗2n
考虑比 f ( n − 1 , n ) f ( n − 1 , n ) f(n−1,n)大的情况,化简之后发现只需在 [ n − 2 k , n ] [ n − 2 k , n ] [n−2k,n]内暴力。
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 114514;
ll a[maxn];
//struct Node {
// int id;
// int x;
//} node[maxn];
//
//bool cmp(Node x, Node y) {
// if (x.x != y.x)return (x.x > y.x);
// else return (x.id < y.id);
//}
int main() {
int T;
cin >> T;
while (T--) {
ll n, k;
cin >> n >> k;
for (int i = 1; i <= n; i++)
cin >> a[i];
ll ans = n*(n-1)-k*(a[n]|a[n-1]);
for (ll i = n; i >= 2; i--) {
if (ans > i * (i - 1))
break;
for (ll j = i - 1; j >= 1; j--) {
ans = ((j * i - k * (a[i] | a[j])) > ans) ? (j * i - k * (a[i] | a[j])) : ans;
// cout << j * i - k * (a[i] | a[j])<<endl;
// cout << ans << endl;
if (ans >= i * j) break;
}
}
cout << ans << endl;
}
}