HDU2204 Eddy's爱好(容斥原理)

题目问[1,n]有几个数是$m^k (k>1)$形式。

如果这样考虑,m已知k未知,对于每一个m统计其k的数量即$\lfloor log_mn \rfloor$个,再容斥,然而m太多了,完全不可行。

而k远远比m还少,应该反过来考虑,m未知k已知,对于每一个k统计其m的数量,即$\lfloor \sqrt[k]n \rfloor$个。

由于$n \leqslant 10^{18}$,而$2^{60} > 10^{18}$,所以k的范围就是小于60的整数。

然而60用容斥$2^{60}$还是不可行,而$m^{a \times b}$,已知就被$m^a$和$m^b$计数过了,所以对于所有60以内的合数完全可以在一开始就除去,即只考虑60以内的质数。

而60以内的质数只有17个,那么就OK了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 using namespace std;
 5 int prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61};
 6 int main(){
 7     long long n;
 8     while(~scanf("%lld",&n)){
 9         int pn=0;
10         while((1LL<<prime[pn+1])<=n) ++pn;
11         long long res=0;
12         for(int i=1; i<(1<<pn); ++i){
13             long long tmp=1; int cnt=0;
14             for(int j=0; j<pn; ++j){
15                 if(((i>>j)&1)==0) continue;
16                 tmp*=prime[j]; ++cnt;
17             }
18             if(cnt&1) res+=(long long)(pow(n,1.0/tmp)+1e-8);
19             else res-=(long long)(pow(n,1.0/tmp)+1e-8);
20         }
21         printf("%lld\n",res+1);
22     }
23     return 0;
24 }

HDU2204 Eddy's爱好(容斥原理)

时间: 2024-10-13 17:18:22

HDU2204 Eddy's爱好(容斥原理)的相关文章

hdu2204 Eddy&#39;s爱好 打表+容斥原理

Ignatius 喜欢收集蝴蝶标本和邮票,但是Eddy的爱好很特别,他对数字比较感兴趣,他曾经一度沉迷于素数,而现在他对于一些新的特殊数比较有兴趣.这些特殊数是这样的:这些数都能表示成M^K,M和K是正整数且K>1.正当他再度沉迷的时候,他发现不知道什么时候才能知道这样的数字的数量,因此他又求助于你这位聪明的程序员,请你帮他用程序解决这个问题.为了简化,问题是这样的:给你一个正整数N,确定在1到N之间有多少个可以表示成M^K(K>1)的数. 打表+容斥原理 1 #include<stdi

容斥定理 hdu2204 Eddy&#39;s爱好

传送门:点击打开链接 很明显会有大量重复的被计算,所以很容易就想到容斥定理. 我们设dp[i]表示能表示成M^i(i>1)且i是这个数字能表示出来的最大的情况时的总类数 比如,27拆成M^K时的K最大能表示成3,所以27这个数字分在dp[3]这一类 1我们暂时不考虑,不把它放在任何一类 因为K>1,所以K至少是2,最大是2^K=N的时候,所以K最大等于log2(N),所以K非常的小 首先,求出K最大大概的位置 然后开始求dp[i].求法如下: 首先,1~N中有哪些是能拆分成M^i的,利用pow

HDU2204 Eddy&#39;s爱好

题意:问[1,n]有几个是m^k的形式(m>0,k>1, n<=1e18) 题解:枚举m,会发现很多,所以枚举k,可以发现k<=63那么只要每个k计算pow(n , 1/k),接下来去重,可以用容斥来做,2^61的复杂度,这里考虑m^k = m^(k1+k2)一个合数可以分解为素数,那么只要对素数容斥就可以了 #include <bits/stdc++.h> #define maxn 101000 #define INF 0x3f3f3f3f typedef long

【HDU2204】Eddy&#39;s爱好

题目大意:求从 1 到 N 中共有多少个数可以表示成 \(M^K,K \gt 1\).\(N \le 1e18\) 题解: 发现 N 很大,若直接枚举 M 的话有 1e9 级别的数据量,肯定超时,因此考虑枚举幂次.发现对于幂次为 k 的符合条件的数有 N 开 K 次方下取整个,同时注意到 k 的取值范围最大为 60,因为 2 的 60 次方为 1e18 级别.因此考虑从小到大进行枚举幂次即可,但是发现有些数字会产生重复,如:\((2^3)^2=(2^2)^3=2^6\),即:同一个数字被计入了三

HDU 2204 Eddy&#39;s爱好(容斥原理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2204 解题报告:输入一个n让你求出[1,n]范围内有多少个数可以表示成形如m^k的样子. 不详细说了,自己一开始也忽略了三个素数的乘积的乘方的情况. 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6

[容斥原理] hdu 2204 Eddy&#39;s爱好

题意: 中文题目! 思路: 首先 M^k可以分解成 (M^(k*p)) p是素数 这么我们只要枚举素因子就好了 由于数据 所以只要枚举60以内的素数就够了 然后因为2*3*5*7就超过60了 做容斥原理就最多就只有三次 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #inclu

【容斥】 HDU 2204 Eddy&#39;s爱好

通道 题意:给你一个正整数N,确定在1到N之间有多少个可以表示成M^K(K>1)的数. 思路:我们可以由n^(1/p),知道指数为p的有多少个数. 通过观察,可以发现若一个数可以表示成x^(k*t),则可以表示成(x^k)^t.因此指数必然为素数. 枚举素数便可以得到指数为p的个数,但是可能出现重复,例如:x^3=y^5,其中x=t^5,y=t^3. 运用容斥原理,设a[i]表示指数为第i个素数的个数,那么答案等于满足一个的,减去两个的,加上三个的…… 由于2^60>10^18,2*3*5*7

C - Eddy&#39;s爱好

C - Eddy's爱好 Time Limit:1000MS    Memory Limit:32768KB    64bit IO Format:%I64d & %I64u SubmitStatus Description Ignatius 喜欢收集蝴蝶标本和邮票,但是Eddy的爱好很特别,他对数字比较感兴趣,他曾经一度沉迷于素数,而现在他对于一些新的特殊数比较有兴趣. 这些特殊数是这样的:这些数都能表示成M^K,M和K是正整数且K>1. 正当他再度沉迷的时候,他发现不知道什么时候才能知道

ACM 容斥原理

VJ 点击打开链接 参考 点击打开链接 非常好的译文:点击打开链接 容斥原理的想法就是求多个集合的并集.所以要先设计好集合. 组合数学问题中,正面解决会困难,常用方法是正难则反,使用容斥原理求反向在用全集减去.将对立面的限制条件分析清楚. eg 求区间互质的数的个数,则用除法等计算出一个数的倍数的方法再减去. UVa 11806 Cheerleaders 求k个石子放在n*m的矩阵里 并且第一行 最后一行 第一列 最后一列都要有石子 考虑反面 求出所有的 减去不满足的情况 容斥原理总共4个 集合