hdu 6053 TrickGCD(筛法+容斥)
TrickGCD
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2649 Accepted Submission(s): 1007
* 1≤Bi≤Ai
* For each pair( l , r ) (1≤l≤r≤n) , gcd(bl,bl+1...br)≥2
Each test case begins with an integer number n describe the size of array A.
Then a line contains n numbers describe each element of A
You can assume that 1≤n,Ai≤105
看范围就知道要去枚举gcd,对于每个gcd,在a[i]这个位置上有gcd/a[i]个数能满足条件构成b[i],只要把每个位置求出来累乘就好了,但是这个过程还需要优化。
优化可以用素数筛法类似的方式,把gcd/a[i]相同的数都一起处理,这样在用一个快速幂把相同的那些情况数算出来,时间复杂度就是n*logn*logn。
但是答案显然会有重复,赛时就是这个问题不会解决然后gg。
dp[i]表示 gcd=i 时求出的符合情况数,显然它包含了 i 的倍数对应的情况,我们需要把这些数减去,但是倍数的情况显然也有重复,比较复杂。
这个过程我们可以倒过来从上界往下去容斥,这样每次对于num[i]来说,它的倍数的情况都是已经处理好了的,只要依次减去倍数的情况了,其实相当于一个dp的过程。。
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<cmath>
using namespace std; const long long mod=1e9+;
int sum[],a[];
long long dp[]; int n,T,k;
long long poww(long long a, long long b)
{
long long ans=;
while(b)
{
if (b&) ans=(ans*a)%mod;
b>>=;
a=(a*a)%mod;
}
return ans;
}
int main()
{
scanf("%d",&T);
for(int cas=;cas<=T;cas++)
{
memset(sum,,sizeof(sum)); scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
sum[a[i]]++;
}
for(int i=;i<=1e5;i++) sum[i]+=sum[i-]; for(int i=;i<=1e5;i++) // gcd=i
{
dp[i]=;
for(int j=;j<=1e5;j+=i)
{
if (j+i->) k=sum[]-sum[j-];
else if (j==) k=sum[+i-];
else k=sum[j+i-]-sum[j-]; //k表示a序列中,数字范围在[j,j+i-1]的个数,分段
int knum=j/i; // 该范围的数字,对于gcd=i的倍数的个数相同 if (knum== && k>) dp[i]=; //如果这范围的数字存在,但是,要gcd==i没有数字可选,那么这个gcd无解,不存在可行解
else dp[i]=(dp[i]*poww(knum,k))%mod;
}
} for(int i=1e5;i>=;i--)
for(int j=i+i;j<=1e5;j+=i)
{
dp[i]-=dp[j];
dp[i]=(dp[i]+mod)%mod;
}
long long ans=;
for(int i=;i<=1e5;i++)
ans=(ans+dp[i])%mod;
printf("Case #%d: %lld\n",cas,ans);
}
return ;
}
hdu 6053 TrickGCD(筛法+容斥)的更多相关文章
- hdu 6053 trick gcd 容斥
http://acm.hdu.edu.cn/showproblem.php?pid=6053 题意:给定一个数组,我们定义一个新的数组b满足bi<ai 求满足gcd(b1,b2....bn)&g ...
- hdu 6053 TrickGCD 筛法
TrickGCD Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Probl ...
- 2017ACM暑期多校联合训练 - Team 2 1009 HDU 60563 TrickGCD (容斥公式)
题目链接 Problem Description You are given an array A , and Zhu wants to know there are how many differe ...
- HDU 6053 TrickGCD 莫比乌斯函数/容斥/筛法
题意:给出n个数$a[i]$,每个数可以变成不大于它的数,现问所有数的gcd大于1的方案数.其中$(n,a[i]<=1e5)$ 思路:鉴于a[i]不大,可以想到枚举gcd的值.考虑一个$gcd( ...
- 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 ...
- HDU 6053 - TrickGCD | 2017 Multi-University Training Contest 2
/* HDU 6053 - TrickGCD [ 莫比乌斯函数,筛法分块 ] | 2017 Multi-University Training Contest 2 题意: 给出数列 A[N],问满足: ...
- HDU 6053 ( TrickGCD ) 分块+容斥
TrickGCD Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- HDU 6053 TrickGCD(莫比乌斯反演)
http://acm.hdu.edu.cn/showproblem.php?pid=6053 题意:给出一个A数组,B数组满足Bi<=Ai. 现在要使得这个B数组的GCD值>=2,求共有多 ...
- HDU 6053 TrickGCD(分块)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6053 [题目大意] 给出一个数列每个位置可以取到的最大值, 问这个可以构造多少个数列,使得他们的最 ...
随机推荐
- 如何通过包名打开手机里的APP
目前已知的打开APP的方式有两种, 一种是通过openUrl打开,这种有一个严重的问题,即必须添加白名单,白名单之外的APP即时安装了也无法打开. 另一种就是今天的重点,通过包名打开APP.先上核心代 ...
- hdfs启动后进入safe mode,Problem connecting to server
原创文章:http://blog.csdn.net/renfengjun/article/details/25320043 DN中日志如下: 2017-06-17 06:35:59,242 WARN ...
- Hbase1.0伪分布式集群启动失败问题
作者:Syn良子 出处:http://www.cnblogs.com/cssdongl/p/7340681.html 转载请注明出处 最近抽空折腾自己的虚拟机环境时启动伪分布式Hbase集群一直失败, ...
- deeplenrnig学习笔记——什么是特征
特征是机器学习系统的原材料,对最终模型的影响是毋庸置疑的.如果数据被很好的表达成了特征,通常线性模型就能达到满意的精度. 一.特征的表示粒度: 学习算法在一个什么粒度上的特征表示,才有能发挥作用 ...
- $ 一步一步学Matlab(1)——初识Matlab
本文分四步走策略:第一,Matlab是个什么玩意:第二,为什么要学Matlab:第三,怎样轻松.无痛.少走弯路地学习Matlab:第四,怎样写一个Matlab的Hello World.通过这四步走,达 ...
- Ubuntu16.04安装Jenkins
Jenkins基于JAVA,所以需要先安装jdk 安装java 在官网上下载jdk,http://www.oracle.com/technetwork/java/javase/downloads/jd ...
- 20145307《信息安全系统设计基础》第五周学习总结PT2
20145307<信息安全系统设计基础>第五周学习总结PT2: 教材学习内容总结 之前有第一部分学习总结: http://www.cnblogs.com/Jclemo/p/5962219. ...
- 20145331 《Java程序设计》第6周学习总结
20145331 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 输入/输出 10.1.1串流 •Java将输入/输出抽象化为串流,数据有来源及目的地,衔 ...
- 动态 K th
每一棵线段树是维护每一个序列前缀的值在任意区间的个数,如果还是按照静态的来做的话,那么每一次修改都要遍历O(n)棵树,时间就是O(2*M*nlogn)->TLE考虑到前缀和,我们通过树状数组来优 ...
- python-运算、分支、深浅拷贝
算术表达式: + - * / 除法Python3中是默认向浮点数靠拢 //取整运算 结果的最小整数靠拢 向下 5 // 2 = 2(向下取整) %取余运算 5 % 2 = 1 **幂值运算 ...