Codeforces Round #735 (Div. 2)-B. Cobb-题解

63 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

@TOC

Codeforces Round #735 (Div. 2)-B. Cobb

传送门 Time Limit: 1 second Memory Limit: 256 megabytes

Problem Description

You are given nn integers a1,a2,,ana_1, a_2, \ldots, a_n and an integer kk. Find the maximum value of ijk(aiaj)i \cdot j - k \cdot (a_i | a_j) over all pairs (i,j)(i, j) of integers with 1i<jn1 \le i < j \le n. Here, | is the bitwise OR operator.

Input

The first line contains a single integer tt (1t100001 \le t \le 10\,000) — the number of test cases.

The first line of each test case contains two integers nn (2n1052 \le n \le 10^5) and kk (1kmin(n,100)1 \le k \le \min(n, 100)).

The second line of each test case contains nn integers a1,a2,,ana_1, a_2, \ldots, a_n (0ain0 \le a_i \le n).

It is guaranteed that the sum of nn over all test cases doesn't exceed 31053 \cdot 10^5.

Output

For each test case, print a single integer — the maximum possible value of ijk(aiaj)i \cdot j - k \cdot (a_i | a_j).

Sample Input

4
3 3
1 1 3
2 2
1 2
4 3
0 1 2 3
6 6
3 2 0 0 5 6

Sample Onput

-1
-4
3
12

Note

Let f(i,j)=ijk(aiaj)f(i, j) = i \cdot j - k \cdot (a_i | a_j).

In the first test case,

So the maximum is f(1,2)=1f(1, 2) = -1.

In the fourth test case, the maximum is f(3,4)=12f(3, 4) = 12.


题目大意

给你一个数组aa和一个正整数kk,让你从中选取不同的两个数a[i]a[i]a[j]a[j],计算ijk(a[i]a[j])i*j-k*(a[i]\|a[j])的最大值。

解题思路

暴力解题需要复杂度O(n2)O(n^2)会超时,所以需要进行优化。

有没有发现这一题的kk很特殊,kk不会超过100100也不会超过n (na[i])n\ (n\geq a[i])

那么kk是什么?kk就是要减去的那个或结果的系数。

如果不需要减去这么一个kk,那么iijj肯定选最大的两个nnn1n-1

这个“讨厌”的kk让我们减去了多少呢?最多减去100100倍的或结果。而a[i],a[j]na[i],a[j]\leq na[i]a[j]<2×na[i]|a[j]<2\times n,所以由kk造成的影响最多不超过200×n200\times n

如果nn特别大,那么选择后面的元素的话iijj就会非常大,大约是n×nn\times n,与kk造成的影响200×n200\times n相差一个nn200200

所以iijj不会小于n200n-200。也就是说前面数据再多,都是没有意义的。我们只需要考虑后200200个数据就够了。

分析一下复杂度

每组测试样例复杂度为O(min(n2,2002))O(min(n^2, 200^2)), 每组数据有nn个的话最多有3×105/n3\times10^5/n组数据, 粗略估算复杂度就是O(3×105min(n,200))O(6×106)O(3\times10^5*min(n, 200))\leq O(6\times10^6)

代码实现就不困难了。


AC代码

记得用 long longlong\ long,需要相乘的i,ji,j也要用 long longlong\ long

#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
ll a[100010];
int main()
{
    int N;
    cin>>N;
    while(N--)
    {
        int n,k;
        cd(n),cd(k);
        for(int i=1;i<=n;i++)
            scanf("%lld", &a[i]);
        ll ans=-1000000000000000000;
        for(ll i=n;i>=max(1, n-200);i--)
            for(ll j=i-1;j>=max(1, n-200);j--)
                ans=max(ans,i*j-k*(a[i]|a[j]));
        printf("%lld\n",ans);
    }
    return 0;
}

同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:letmefly.blog.csdn.net/article/det…