KSzsh

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

Even Subarrays(数论问题)

题目链接

题目描述:

You are given an integer array a1,a2,,an(1ain).

Find the number of subarrays of a whose XOR has an even number of divisors. In other words, find all pairs of indices (i,j)(ij) such that aiai+1aj has an even number of divisors.

For example, numbers 2,3,5 or 6 have an even number of divisors, while 1 and 4 — odd. Consider that 0 has an odd number of divisors in this task.

Here XOR (or ) denotes the bitwise XOR operation.

Print the number of subarrays but multiplied by 2022... Okay, let's stop. Just print the actual answer.

输入描述:

Each test contains multiple test cases. The first line contains the number of test cases t(1t104). Description of the test cases follows.

The first line of each test case contains a single integer n(2n2105) — the length of the array a.

The second line contains n integers a1,a2,,an(1ain).

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

输入描述:

For each test case, print the number of subarrays, whose XOR has an even number of divisors.

样例:

input:

4
3
3 1 2
5
4 2 1 5 3
4
4 4 4 4
7
5 7 3 7 1 7 3

output:

4
11
0
20

Note:

In the first test case, there are 4 subarrays whose XOR has an even number of divisors: [3],[3,1],[1,2],[2].

In the second test case, there are 11 subarrays whose XOR has an even number of divisors: [4,2],[4,2,1],[4,2,1,5],[2],[2,1],[2,1,5],[2,1,5,3],[1,5,3],[5],[5,3],[3].

In the third test case, there is no subarray whose XOR has an even number of divisors since XOR of any subarray is either 4 or 0.

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
int T = 1;
LL n;
void solve()
{
scanf("%lld", &n);
vector<int> a(n), b(2 * n); // 开两个vector,一个用于存数组,一个用于存某个数出现的次数
a.clear(), b.clear();
for (int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
LL cnt = 0; // 存储异或和的因数为奇数个的数的个数
int t = 0;
b[t]++; // a[0] ^ a[0]为0
for (int i = 0; i < n; i++)
{
t ^= a[i];
// n个数可能的异或最大值肯定小于2 * n
// 判断某个数的因数是否为奇数的条件就是判断其是否是完全平方数
for (LL j = 0; j * j < 2 * n; j++)
{
// 一个数 t 异或一个完全平方数 p 的结果 x,该结果 x 异或 t 的结果必定是那个完全平方数 p,只要 x 存在,则 j * j 必存在
// t 是 1-i 的异或和,假设 p 是 j-i 的异或和,则 x 就是 1-(j-1) 的异或和,所以 x ^ p = t,所以此时只需要判断 x 出现过的次数即可
if ((t ^ (j * j)) < 2 * n)
{
cnt += b[t ^ (j * j)]; // cnt 加上这个数出现过的次数
}
}
b[t]++; // t的出现的次数加一
}
LL ans = (n * (n + 1) / 2) - cnt; // 总共的个数减去不成立的个数即为成立的个数
printf("%lld\n", ans);
}
int main()
{
// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
scanf("%d", &T);
while (T--)
{
solve();
}
return 0;
}

posted on   KSzh  阅读(43)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示