D. Exam in MAC

D. Exam in MAC

The Master's Assistance Center has announced an entrance exam, which consists of the following.

The candidate is given a set s of size n and some strange integer c. For this set, it is needed to calculate the number of pairs of integers (x,y) such that 0xyc, x+y is not contained in the set s, and also yx is not contained in the set s.

Your friend wants to enter the Center. Help him pass the exam!

Input

Each test consists of multiple test cases. The first line contains a single integer t (1t2104) — the number of test cases. The description of the test cases follows.

The first line of each test case contains two integers n and c (1n3105, 1c109) — the size of the set and the strange integer.

The second line of each test case contains n integers s1,s2,,sn (0s1<s2<<snc) — the elements of the set s.

It is guaranteed that the sum of n over all test cases does not exceed 3105.

Output

For each test case, output a single integer — the number of suitable pairs of integers.

Example

input

8
3 3
1 2 3
1 179
57
4 6
0 3 5 6
1 1
1
5 10
0 2 4 8 10
5 10
1 3 5 7 9
4 10
2 4 6 7
3 1000000000
228 1337 998244353

output

3
16139
10
2
33
36
35
499999998999122959

Note

In the first test case, the following pairs are suitable: (0,0), (2,2), (3,3).

In the third test case, the following pairs are suitable: (0,1), (0,2), (0,4), (1,3), (2,6), (3,4), (3,5), (4,5), (4,6), (5,6).

 

解题思路

  正着不好算,考虑容斥原理反过来做。用总的数对,减去满足 x+yS 的数对数量,减去 yxS 的数对数量,最后加上同时满足 x+ySyxS 的数对数量,就是要求的答案。

  其中总的数对就是 (c+1)+c+(c1)++1=(c+1)(c+2)2

  满足 x+yS 的数对数量。由于 0xyx+y=si,则有 0xsix,解得 0xsi2。由于 xy 一一对应,因此只用考虑 x 的数量,即 si2+1。由于每个 si 都不同,因此总的数对数量就是 i=1nsi2+1

  满足 yxS 的数对数量。同理解得 siyc,总的数对数量就是 i=1ncsi+1

  同时满足 x+ySyxS 的数对数量。意味着同一个数对 (x,y) 被减了 2 次,即满足 {x+y=siyx=sji 可以等于 j。有 x=sisj2y=si+sj2,意味着 sisj 的奇偶性要相同。假设有 c0 个偶数的 sic1 奇数的 si,那么数对数量就是 Cc02+Cc12

  AC 代码如下,时间复杂度为 O(n)

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 3e5 + 10;

int a[N];

void solve() {
    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%d", a + i);
    }
    LL ret = (m + 1ll) * (m + 2ll) / 2;
    int c0 = 0, c1 = 0;
    for (int i = 0; i < n; i++) {
        ret -= a[i] / 2 + 1 + m - a[i] + 1;
        if (a[i] & 1) c1++;
        else c0++;
    }
    ret += c0 * (c0 + 1ll) / 2 + c1 * (c1 + 1ll) / 2;
    printf("%lld\n", ret);
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        solve();
    }
    
    return 0;
}

 

参考资料

  Codeforces Round #932 (Div. 2) Editorial:https://codeforces.com/blog/entry/126662

posted @   onlyblues  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2022-03-06 正则问题
2022-03-06 树的DFS
Web Analytics
点击右上角即可分享
微信分享提示