首页 > 其他分享 >   Codeforces Round #841 (Div. 2) and Divide by Zero 2022 -----C. Even Subarrays

  Codeforces Round #841 (Div. 2) and Divide by Zero 2022 -----C. Even Subarrays

时间:2022-12-28 20:12:55浏览次数:34  
标签:Even std 平方 Divide 841 int 个数 异或 除数

题目链接:https://codeforces.com/contest/1731/problem/C

 

 题目的大致意思是:给长度为n的数组,求  子数组的异或和   的 结果 的 除数个数 为 偶数个 的 子数组 有多少个。

例如:4的除数有1,2,4,有三个,所以4的除数为奇数个;8的除数有1,2,4,8,有四个,所以8的除数有偶数个;

通过题意,我们可以发现,这题的切入点在于 异或和 与 除数个数为偶数 ;

首先,我们先想一个数x,他的除数的个数为偶数的时,x会有什么特点。

我们可以想到,如果y是x的除数,那么x/y也是x的除数,当y与x/y不相等的时候,x的除数会增加2个;

                         当y与x/y相等的时候,x的除数会增加1个;

而y与x/y相等的条件在于,x是y的平方;

                    于是,我们可以知道,当一个数是平方数的时候,他的除数个数为奇数个;

观察n的范围是2e5,可以发现平方数大致在1e3左右(不到),可以先预处理出平方数;

那么除数的个数为偶数我们已经解决了,接下来就是解决异或和的事情;

在我们知道哪些数满足除数的个数是偶数的时候,我们会先暴力的想到,枚举每个区间,去计算他们的异或和,是否是平方数。

显然,暴力是不行,时间复杂度不能让我们这样子去做。

于是,我们可以思考异或前缀和,异或具有一个比较好的性质在于,x^y = z--->y^z = x,x^z = y;

    假设当前我们异或到第i个数的结果是x,然后假设y是一个平方数,那么x^y得到的结果z,如果z在后面前缀异或和中出现了(假设是第j个);

    根据前缀异或和的性质,z^x就是[ i , j ]这段区间异或和的结果,然后因为x^y = z,可以得到z^x = y,而y是平方数;

    那么我们就可以枚举平方数去和x进行异或,看后面z出现的个数,然后减去即可;

时间复杂度O(700N);

代码如下:

#include<bits/stdc++.h>

int odd[550000], op = 0;

signed main()
{
    std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0);

    for (int i = 0; i * i <= 5e5; ++i)//预处理出5e5以内的平方数,
        odd[op++] = i * i;            //为什么不是2e5,是因为异或后出现的结果可能会比原来大
                                    //所以需要多预处理一些
    std::vector<int> MP(262144 * 2, 0);//记录前缀异或和出现的个数
    int T; std::cin >> T;
    while (T--)
    {
        int n; std::cin >> n;
        int pre = 0;
        std::vector<int> nums(n + 1, 0);
        for (int i = 1; i <= n; ++i)
            std::cin >> nums[i], pre ^= nums[i], MP[pre]++;
        long long ans = 0; pre = 0;
        for (int i = 1; i <= n; ++i)
        {
            int cnt = 0; pre ^= nums[i]; MP[pre]--; pre ^= nums[i];//这里稍微有点绕
            for (int k = 0; k < op; ++k)                //需要先把当前的前缀异或和给减去,因为0^pre的话,会重复计数
            {
                cnt += MP[pre ^ odd[k]];
                if (odd[k] == nums[i])cnt++;
            }
            ans += (n - i - cnt + 1); pre ^= nums[i];//把满足的结果累加
        }
        std::cout << ans << "\n";
    }

    return 0;
}

这题需要想到平方数和异或前缀和,需要分开来想。(一开始是想 异或和 与  除数个数为偶数的关系是什么,结果想了好久,悲~还得训训)

标签:Even,std,平方,Divide,841,int,个数,异或,除数
From: https://www.cnblogs.com/ACMER-XiCen/p/17011177.html

相关文章

  • Codeforces Round #841 (Div. 2) and Divide by Zero 2022
    CodeforcesRound#841(Div.2)andDividebyZero2022o(╥﹏╥)o2022的最后一场也没打好B题反正我是理解错了,我看到题目上写着要相乘再取模,结果就真的去先乘再取模,这......
  • C. Even Subarrays
    CodeforcesRound#841(Div.2)andDividebyZero2022题目大意给定一个数组,求满足所有元素异或的结果有偶数个因子的子数组的个数。本题将0视作有奇数个因子。解题......
  • Codeforces Round #841 (Div. 2) and Divide by Zero 2022
    A.JoeyTakesMoney题意:给定n个整数,每次操作可以选择两个整数,获得两数之积,再构造一组(x,y)使得x*y等于两数之积,并将原来的数替换为x,y,求操作若干次后n个数......
  • CF--841--C
    关键当时确实是想到了使用减法,但是没有想明白怎么快速查找异或为n*n的这种数其实也就是反向查找xaa=x,也就异或两次后就不变了,在异或一次,其实也就是把前面的某段区间给去......
  • mysql Event、存储过程、表命令
     Mysql事件调度器(EventScheduler)类似于定时器,可以在某一个时间点执行一个SQL语句或一个语句块(BEGIN...END);或者每隔固定间隔重复执行。类似于Linux下的crontab,或Windows......
  • Netty中8大组件详解(EventLoop、Channel、ChannelFuture、Future、 Promise、Handler
    Netty概述1、什么是NettyNettyisanasynchronousevent-drivennetworkapplicationframeworkforrapiddevelopmentofmaintainablehighperformanceprotocol......
  • python线程之event事件
    fromthreadingimportThread,Eventimporttimeevent=Event()deflight():print('红灯亮着,所有车都要等待')time.sleep(3)print('绿灯亮了,可以出......
  • Why am I getting a DIA8411C A file "" could not be found in the db2diag.log?
    IBMSupportWhyamIgettingaDIA8411CAfile""couldnotbefoundinthedb2diag.log? https://www.ibm.com/support/pa......
  • 基于AD Event日志监测域内信息探测行为
    01、简介当攻击者获得内网某台域内服务器的权限,就会以此为起始攻击点,尽可能地去收集域的信息,以获取域控权限作为内网的终极目标。例如,攻击者会在内网中收集域管理员用户列......
  • FreeSWITCH学习笔记:EventSocket
    本文更新于2022-12-20,使用FreeSWITCH1.10.7。目录apiauthbgapiconnectdivert_eventseventexitfilterfilterdeletelingerlogmyeventsnixeventnoeventnolingernologsendev......