E 算式子

https://ac.nowcoder.com/acm/contest/6290/E

 

由题目给出的式子可知,这道题要分为两个部分来计算。

首先我们来看看啊  “a[]/x” 这一部分

        我们先预处理出在范围内的所有数字的出现次数,计算出前缀和

                             然后计算出每一个倍数范围内的数字个数(因为要取整,所以这样做)

        再乘以这个倍数即可

再来看看另一部分

        用a【】来储存预处理出有倍数关系的次数;

        然后计算的时候,我们就依次前缀和相加即可

        举个例子  比如n=1,m=4,val[1]=2

            那么当x=1时,ans为0

                   当x=2时,ans为1

              当x=3时,ans为1

              当x=4时,ans为2

        那么,我们的预处理数组在处理的时候呢,就是a【1】= 0

                             a【2】= 1

                             a【3】= 0

                             a【4】=1

      前缀和相加之后,就能得出上面的结果

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3   
 4 int n,m,V[2000005]={0},S[2000005]={0};
 5 long long t,ans=0,a[2000005]={0};
 6 int main()
 7 {
 8     int i,j,l,r;
 9     scanf("%d%d",&n,&m);
10     for(i=1;i<=n;i++)scanf("%d",&j),V[j]++;
11     for(i=1;i<=m;i++)
12     {
13         S[i]=S[i-1]+V[i];
14         for(j=i;j<=m;j+=i)
15             a[j]+=V[i];
16     }
17     for(i=1;i<=m;i++)
18     {
19         a[i]+=a[i-1],t=a[i];
20         for(j=i;j<=m;j+=i)
21         {
22             l=j,r=min(j+i-1,m);
23             t+=(long long)j/i*(S[r]-S[l-1]);
24         }
25         ans^=t;
26     }
27     printf("%lld\n",ans);
28     return 0;
29 }

 

posted @ 2020-07-14 23:10  古比  阅读(167)  评论(0编辑  收藏  举报