【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=6053

【题目大意】

  给出一个数列每个位置可以取到的最大值,
  问这个可以构造多少个数列,使得他们的最大公约数大于1

【题解】

  我们可以枚举最大公约数k,对于k来说,
  他对答案的贡献为∏[ai/k],我们将数列中的数字转化为权值数组
  ∏_{i=1}^{100000}[i/k],对于求解i/k的部分我们可以进行数值分块,
  j*k-1~j*k+k-1的数值除k得到的结果都是相同的,因此可以直接求这个结果的幂次,
  这时候只要再加一个权值数组的前缀和,问题就迎刃而解了。
  数值分块计算的复杂度为n+n/2+n/3+n/4+n/5+……+n/n=nlogn。
  对于计算结果,我们需要进行容斥,奇数次素数乘的系数为1,偶数次素数乘的系数为-1,
  对于出现素数幂的合数其系数为0,
  我们发现这个容斥恰好是莫比乌斯函数的相反数,因此我们取反即可。
  这有个小小的优化,对于系数为0的情况,我们可以直接跳过,不进行计算。

【代码】

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=200010;
typedef long long LL;
const LL mod=1000000007;
int T,n,a[N],b[N],cnt[N],cas=1,p[N];
LL ans=0;
int tot,miu[N],sum[N],v[N];
void read(int&a){
char ch;while(!((ch=getchar())>='0')&&(ch<='9'));
a=ch-'0';while(((ch=getchar())>='0')&&(ch<='9'))a*=10,a+=ch-'0';
}
void mobius(int n){
int i,j;
for(miu[1]=1,i=2;i<=n;i++){
if(!v[i])p[tot++]=i,miu[i]=-1;
for(j=0;j<tot&&i*p[j]<=n;j++){
v[i*p[j]]=1;
if(i%p[j])miu[i*p[j]]=-miu[i];else break;
}
}for(i=1;i<n;i++)sum[i]=sum[i-1]+miu[i];
}
LL pow(LL a,LL b,LL p){if(b==0)return 1;LL t=1;for(a%=p;b;b>>=1LL,a=a*a%p)if(b&1LL)t=t*a%p;return t;}
int main(){
read(T);
mobius(100000);
while(T--){
read(n);
ans=0; int mn=~0U>>1,mx=0;
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++)read(a[i]),mn=min(a[i],mn),mx=max(a[i],mx),cnt[a[i]]++;
for(int i=1;i<=200000;i++)cnt[i]+=cnt[i-1];
for(int i=2;i<=mn;i++){
if(!miu[i])continue;
LL tmp=1;
for(int j=1;i*j<=100000;j++)tmp=tmp*pow(j,cnt[i*j+i-1]-cnt[i*j-1],mod)%mod;
// j<=100000/i -> i*j<=100000 : TLE -> AC
ans=(ans-tmp*miu[i]+mod)%mod;
}printf("Case #%d: %lld\n",cas++,ans);
}return 0;
}

HDU 6053 TrickGCD(分块)的更多相关文章

  1. HDU 6053 ( TrickGCD ) 分块+容斥

    TrickGCD Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  2. HDU 6053 - TrickGCD | 2017 Multi-University Training Contest 2

    /* HDU 6053 - TrickGCD [ 莫比乌斯函数,筛法分块 ] | 2017 Multi-University Training Contest 2 题意: 给出数列 A[N],问满足: ...

  3. 2017 多校2 hdu 6053 TrickGCD

    2017 多校2 hdu 6053 TrickGCD 题目: You are given an array \(A\) , and Zhu wants to know there are how ma ...

  4. HDU 6053 TrickGCD 莫比乌斯函数/容斥/筛法

    题意:给出n个数$a[i]$,每个数可以变成不大于它的数,现问所有数的gcd大于1的方案数.其中$(n,a[i]<=1e5)$ 思路:鉴于a[i]不大,可以想到枚举gcd的值.考虑一个$gcd( ...

  5. HDU 6053 TrickGCD(莫比乌斯反演)

    http://acm.hdu.edu.cn/showproblem.php?pid=6053 题意:给出一个A数组,B数组满足Bi<=Ai. 现在要使得这个B数组的GCD值>=2,求共有多 ...

  6. hdu 6053 TrickGCD 筛法

    TrickGCD Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Probl ...

  7. hdu 6053 TrickGCD(筛法+容斥)

    TrickGCD Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  8. 2017 Multi-University Training Contest - Team 2 &&hdu 6053 TrickGCD

    TrickGCD Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  9. HDU 6053 TrickGCD —— 2017 Multi-University Training 2

    TrickGCD Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

随机推荐

  1. 炒鸡简单的canvas粒子(山东数漫江湖)

    位图的canvas一直不会被svg比下去的原因了. 俗话说,须弥芥子,是大小之说,也有以小见大之说,颗颗粒子,足以构建宏大效果. 这是一篇炒鸡简单的canvas粒子教程,主要是讲如何粒子特效的原理,一 ...

  2. C++获取系统时间的方法

    //首先是了解这个结构体,_SYSTEMTIME ,然后通过系统函数GetLocalTime往这个结构体的变量中写入当前系统时间typedef struct _SYSTEMTIME { WORD wY ...

  3. 【转】linux下杀死进程

    经过搜集和整理相关的Linux操作系统杀死进程的材料,在这里给大家推荐本篇文章,希望大家看后会有不少收获. 1. kill 作用:根据进程号杀死进程 用法: kill [信号代码] 进程ID 举例: ...

  4. 【R语言学习】时间序列

    时序分析会用到的函数 函数 程序包 用途 ts() stats 生成时序对象 plot() graphics 画出时间序列的折线图 start() stats 返回时间序列的开始时间 end() st ...

  5. 超级rtmp服务器和屌丝wowza

    超级rtmp服务器和屌丝wowza http://blog.csdn.net/win_lin/article/details/11927973

  6. memcached和redis区别

    Memcached:是高性能分布式内存缓存服务器,本质是一个内存 key-value 数据库,但不支持数据持久化,服务器关闭后,数据全丢失.只支持 key-value 结构. Redis:将大部分数据 ...

  7. 【uva10779】收集者的难题

    按照题意建模就行了. #include<bits/stdc++.h> #define naive 0 #define inf 1000000007 using namespace std; ...

  8. C中级 消息队列设计

    引言  - 补充好开始 消息队列在游戏服务器层应用非常广泛. 应用于各种耗时的IO操作业务上.消息队列可以简单理解为 [消息队列 = 队列 + 线程安全]本文参照思路如下, 最后献上一个大神们斗法的场 ...

  9. Shell——Linux/Mac 终端复制文件内容到剪切板

    pbcopy < filename 如: pbcopy < README.md 效果如下: 说明:上图中  # gitskills   即README.md 中内容.

  10. 【Android开发日记】之基础篇(一)——TextView+SpannableStringBuilder

    TextView是控件中最最基础的一个控件,也是最简单的一个控件.但如果仅此,我不会专门为TextView写一篇文章.最近发现了Android中有趣的一个类,那就是标题上写的SpannableStri ...