• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
jacklee404
Never Stop!
博客园    首页    新随笔    联系   管理    订阅  订阅
CF#841-C. Even Subarrays

Codeforces Round#841(Div2) - Even Subarrays

题目传送门

CF题解

相关概念(小学数学)

完全平方数:

​ 一个数如果是另一个整数的完全平方,那么我们称这个数是完全平方数,也叫做平方数。

性质:

  1. 完全平方数末尾只能是0, 1, 4, 5, 6, 9
  2. 奇数的平方的个位数字位奇数,十位数字位偶数

这里推导一下为什么一个数含有奇数个因子,那么其必然是完全平方数(充要条件):

​ 充分性证明: 对于 \(x=p^{a_1}_{1}p^{a_2}_{2}...p^{a_n}_{n}\), 他的因子数可以写成\((a_1 + 1) * (a_2 + 1) * ... *(a_n + 1)\),显然若其因子数为奇数,则对于每一个\(a_i + 1\) 必定为奇数。所以\(a_i\) 为偶数,因此该数为完全平方数。

​ 必要性证明:如果一个数为完全平方数,那么\(x=p^{a_1}_{1}p^{a_2}_{2}...p^{a_n}_{n}\), 且\(x=n^2\) , 那么对于每一个\(p^{a_i}_i\) 其都能化成成\(x_i^2\), 因此其因子数都为偶数。

思路

前缀异或数组, 异或性质

如果枚举每个,i,j显然 \(O(n^2)\)的复杂度会超时,这时我们需要用到异或的性质

\(a \oplus b = c\) , 则\(a \oplus c = b\)

假设我们已经由前缀异或数组,枚举每个区间我们的操作是\(i\le j\)

\(f[i]\oplus f[j - 1] = x^2\) (这里\(0< x < 2n\) 因为异或不会进位,所以我们左移一下,这个数一定不会超过)

由上述性质,得

\(f[i] \oplus x^2=f[j -1]\)

那么我们通过枚举\(f[i]\space, 1\le i \le n\), 再枚举x

最后复杂度\(O(n\sqrt n)\)

#include <iostream>
#include <vector>
using namespace std;
#define ll long long int

const int N = 2e5 + 10;

void solve() {
    long long n, tot; cin >> n;
    vector<int> a(n + 1), arr(2 * n, 0); tot = (n * (n + 1)) / 2;
    int curr = 0;
    arr[0] ++;
    for (int i = 1; i <= n; i ++) {
        cin >> a[i];
        curr ^= a[i];
        for (int k = 0; k * k < 2 * n; k ++) {
            if ((curr ^ (k * k)) < 2 * n) {
                tot -= arr[curr ^ (k * k)];
            }
        }
        arr[curr] ++;
    } 
    cout << tot << "\n";
}
 
int main() {
    ios::sync_with_stdio(false);
    int _;
    cin >> _;
    while (_ --) {
        solve();
    }
}
posted on 2022-12-28 20:36  Jack404  阅读(18)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3