• 牛客练习赛29 算式子


    链接:https://www.nowcoder.com/acm/contest/211/F
    来源:牛客网

    时间限制:C/C++ 2秒,其他语言4秒
    空间限制:C/C++ 262144K,其他语言524288K
    64bit IO Format: %lld

    题目描述

    给定  个整数  。保证 
    对于每个  ,求出 。为了避免过量输出,你只需要将所有的 m 个结果异或起来输出。

    输入描述:

    第一行两个整数  。
    第二行  个整数,第  个表示  。

    输出描述:

    一行一个整数,表示所有结果异或起来的结果。
    示例1

    输入

    复制
    2 2
    1 2

    输出

    复制
    0

    说明

    当 
    x=1
     时,结果为 
    4


    当 
    x=2
    时,结果为  
    4
     。

    所以输出 
    0
    示例2

    输入

    复制
    10 10
    1 3 5 5 2 5 9 3 1 10

    输出

    复制
    60

    备注:

     
     
     
    赛后看了很久旺神的代码,终于看懂了这道题。
    分析:首先我们需要处理两种情况,x在上面和x在下面的情况
               当x在上面时,我们需要记录(1-m)的每个位置产生的贡献,对于当前位置x的贡献,等于它是多少个a[i]的倍数,我们可以将这个倍数关系,进行预处理的向上累加,如果:a[1]=1,a[2]=2,那么我们用cnt[i]表示a数组中i的个数,那么cnt[2]=1,cnt[1]=1,如果我们将倍数累加上去,cnt[2]=2,cnt[1]=1,也就是说在1这个位置产生的贡献为1,在2这个位置产生的贡献为2,当x=2时,我们累加1和2位置的贡献即可,结果为3 ,那么当x为k的时候,我们同样累加1-k的贡献即可,处理的时候可以用前缀和进行处理。
               当x在下面的时候,我们需要找每个ai产生的贡献,对于一个ai,它的贡献可以这样看,设定一个suma数组,让1-ai的值为1,那么当我们跑x的时候,累加上对应的suma[kx]的值即可,比如当前x的值为2,ai为8,那么处理为让suma的下标为1-8的位置+1,
    当前贡献等于suma[x]+suma[2x]+suma[3x]+suma[4x]. 这样的话,我们就可以先跑所有的ai值,处理出最后的suma数组,然后在跑x,并不断累加对应的suma[kx]的值
     
    代码如下:
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include<vector>
    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const int MAXN=2e6+100;
    LL a[MAXN];
    LL cnt[MAXN];
    LL sumb[MAXN];
    LL suma[MAXN];
    LL n,m,x;
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=n;i++)
        {
          scanf("%lld",&a[i]);
          suma[1]++;
          suma[a[i]+1]--;
          cnt[a[i]]++;
        }
    
        for(int i=1;i<=m;i++)
        suma[i]+=suma[i-1];
    
        for(int i=m;i>=1;i--)
        {
           for(int k=i+i;k<=m;k+=i)
           cnt[k]+=cnt[i];
        }
        for(int i=1;i<=m;i++)
        {
         sumb[i]=sumb[i-1]+cnt[i];
        }
    
    
        LL up_x=0;
        LL down_x=0;
        LL ans=0;
        for(int i=1;i<=m;i++)
        {
           down_x=0;
           for(int j=i;j<=m;j+=i)
           down_x+=suma[j];
           up_x=sumb[i];
           ans^=(down_x+up_x);
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    HDU 3068 最长回文
    UVa 1377 / LA 3667 Ruler
    HDU 1540 Tunnel Warfare
    POJ 3450 Corporate Identity
    外贸网站成功运营五个要点
    SEO白帽必备孙子兵法之三十六计
    修改zencart模版的相关资料
    怎么做友情链接,PR值即将更新之际 教你10招快速提升PR值到4
    基于zencart搭建外贸网站流程
    网站内链优化需要考虑的方面
  • 原文地址:https://www.cnblogs.com/a249189046/p/9820976.html
Copyright © 2020-2023  润新知