链接:CF839D

题目大意

给定一个数组大小为\(n(1\leq n\leq 200000)\)的数组\(a\),满足\(1\leq a_i \leq 1000000\)。

选择其中任意\(len\)个数字,若\(gcd>1\),则该组数字对答案贡献为\(len*gcd\),求最终答案对\(1e9+7\)取模。

题目分析

因为\(gcd\)的本质是因数分解,可以想到,如果不考虑算重,那么:

对于一个\(gcd\)的结果\(x\),若有\(num\)个数含有\(x\)这个因数,则被选择的数可形成的形如\(gcd(...)==x\)的贡献为:

\((1*C_{num}^1+2*C_{num}^2+3*C_{num}^3+......+num*C_{num}^{num})*x\)

其中,\(num\)可以直接枚举得到:

\(for(int\ i=x;i<=1000000;i+=x)num[x]+=cnt[i];\)

\(cnt[i]\)表示\(a[\ ]\)中大小为\(i\)的数字的个数,由于时间复杂度是调和级数,可以\(O(nlog(n))\)求解。

由公式可得:

\(1*C_{n}^1+2*C_{n}^2+3*C_{n}^3+......+n*C_{n}^{n}=n*2^{n-1}\)

此处可以\(O(1)\)求得答案,总时间复杂度为\(O(nlog(n))\)。


由于会有重复的情况,我们可以使用容斥去重。

对于每个数的容斥系数,可以附初值:\(tmp[i]=i;\)

由于每个数会在它的因数部分算重,可得:

\(tmp[x]=x- \sum\limits_{d|x}tmp[d];\)

\(tmp\)数组的计算也是调和级数,可以在\(O(nlog(n))\)求解。


综上:

\(ans+=num[x]*2^{num[x]-1}*x*tmp[x];\)

总时间复杂度\(O(nlog(n))\)。

代码实现

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cmath>
  4. #include<algorithm>
  5. #include<cstdio>
  6. #include<iomanip>
  7. #include<cstdlib>
  8. #define MAXN 0x7fffffff
  9. typedef long long LL;
  10. const int N=1000005,mod=1e9+7;
  11. using namespace std;
  12. inline int Getint(){register int x=0,f=1;register char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}return x*f;}
  13. int tmp[N],prime[N];
  14. bool vis[N];
  15. void Pre(int n){
  16. for(int i=2;i<=n;i++)tmp[i]=i;
  17. for(int i=2;i<=n;i++){
  18. if(!vis[i])prime[++prime[0]]=i,vis[i]=1;
  19. for(int j=1;j<=prime[0]&&1ll*i*prime[j]<=n;j++){
  20. vis[i*prime[j]]=1;
  21. if(i%prime[j]==0)break;
  22. }
  23. for(int j=2;1ll*i*j<=n;j++)tmp[j*i]-=tmp[i];
  24. }
  25. }
  26. LL ksm(LL x,LL k){
  27. LL ret=1;
  28. while(k){
  29. if(k&1)ret=ret*x%mod;
  30. x=x*x%mod;
  31. k>>=1;
  32. }
  33. return ret;
  34. }
  35. int cnt[N];
  36. int Query(int x){
  37. int ret=0;
  38. for(int i=x;i<=1000000;i+=x)ret+=cnt[i];
  39. return ret;
  40. }
  41. int main(){
  42. Pre(1000000);
  43. int n=Getint();
  44. for(int i=1;i<=n;i++)cnt[Getint()]++;
  45. LL ans=0;
  46. for(int i=2;i<=1000000;i++){
  47. int x=Query(i);
  48. if(!x)continue;
  49. ans=(ans+x*ksm(2,x-1)%mod*tmp[i]%mod)%mod;
  50. }
  51. cout<<(ans+mod)%mod;
  52. return 0;
  53. }

Codeforces 839D Winter is here的更多相关文章

  1. CodeForces 839D - Winter is here | Codeforces Round #428 (Div. 2)

    赛后听 Forever97 讲的思路,强的一匹- - /* CodeForces 839D - Winter is here [ 数论,容斥 ] | Codeforces Round #428 (Di ...

  2. Codeforces 839D Winter is here - 暴力 - 容斥原理

    Winter is here at the North and the White Walkers are close. John Snow has an army consisting of n s ...

  3. Codeforces 839D Winter is here【数学:容斥原理】

    D. Winter is here time limit per test:3 seconds memory limit per test:256 megabytes input:standard i ...

  4. Codeforces 839D Winter is here(容斥原理)

    [题目链接] http://codeforces.com/contest/839/problem/D [题目大意] 给出一些数,求取出一些数,当他们的GCD大于0时,将数量乘GCD累加到答案上, 求累 ...

  5. codeforces 747D. Winter Is Coming(贪心)

    题目链接:http://codeforces.com/problemset/problem/747/D 题意:冬天有n天,冬天用的轮胎总共能用k天,一开始车子用的是夏天的轮胎. 给出n天的平均气温,温 ...

  6. CodeForces 747D Winter Is Coming

    贪心. 只考虑负数的位置,先填间隔较小的,再填间隔较大的.如果填不满就不填,如果有多余就留给最后一个负数到终点这段路. #include<cstdio> #include<cstri ...

  7. codeforce 839d.winter is here

    题意:如果一个子序列的GCD为1,那么这个子序列的价值为0,否则子序列价值为子序列长度*子序列GCD 给出n个数,求这n个数所有子序列的价值和 题解:首先得想到去处理量比较少的数据的贡献,这里处理每个 ...

  8. Codeforces Round #428 (Div. 2) D. Winter is here 容斥

    D. Winter is here 题目连接: http://codeforces.com/contest/839/problem/D Description Winter is here at th ...

  9. 【23.26%】【codeforces 747D】Winter Is Coming

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

随机推荐

  1. 说说ReactiveCocoa 2

    http://www.cocoachina.com/applenews/devnews/2014/0115/7702.html 转自无网不剩的博客     ReactiveCocoa是Github开源 ...

  2. Detours的使用准备

    Detours是微软开发的一个函数库,可用于捕获系统API.在用其进行程序开发之前,得做一些准备工作: 一.下载Detours 在http://research.microsoft.com/sn/de ...

  3. iOS开发UITouch触摸API简介

    1.UITouch简介 当用户触摸屏幕时,会创建一个UITouch对象: UITouch的作用保存着触摸相关的信息,比如触摸的位置.时间.阶段等: 当从开始到结束,系统会更新UITouch对象,结束时 ...

  4. Git及github使用(三)更新自己的github代码

    如果之前上传的代码到目前有所改动,想要更新github上的代码文件.希望本篇对你有所帮助. 1.拉取代码本地修改后上传代码 提交成功后的效果如下: 2.更新展示在github首页的readme内容 上 ...

  5. i++ 和 ++i 的区别

    先说运算规则吧. i++ 是先赋值后自增:++i 是先自增后赋值. 以下是代码示例: int a=0; int b=0; int i=0; a=i++; System.out.println(&quo ...

  6. java.lang.NoSuchMethodError: com.google.common.hash.HashFunction.hashInt(I)Lcom/google/common/hash/HashCode; 解决办法

    今天在java 上运行spark查询的时候出现一个问题: java.lang.NoSuchMethodError: com.google.common.hash.HashFunction.hashIn ...

  7. <面试题>学习面试

    1.代码中要修改不可变数据会出现什么问题? 抛出什么异常? 代码不会正常运行,抛出 TypeError 异常. # 比如修改元祖.会报错 TypeError: 'tuple' object does ...

  8. sql 循环执行游标

    ---定义开始和结束时间 declare @st_dt datetime declare @en_dt datetime ---时间赋值 ' ' ---定义中间变量 declare @dt datet ...

  9. BigDecimal踩过的大坑

    通常Java中涉及金钱相关的计算为了保持精度,会采用BigDecimal来实现,但是BigDecimal中创建BigDecimal类对象的时候,如果使用直接new的话,必须是String类型的参数,否 ...

  10. Linux CentOS 6.7 挂载U盘

    1. 首先查看U盘是否成功安装fdisk -l 2. 在/mnt下创建U盘目录mkdir /mnt/usb 3. 挂载U盘mount -t vfat /dev/sdb1 /mnt/usb 4. 卸载U ...