首页 > 其他分享 >CF1036F Relatively Prime Powers 题解

CF1036F Relatively Prime Powers 题解

时间:2024-01-22 22:47:02浏览次数:37  
标签:CF1036F prime ge1 int 题解 LL Prime mu pow

题目分析

对于一个不合法的数 \(x(x\ge 2)\),设 \(x=\prod p_i^{r_i}\),令 \(g=\gcd(r_1,r_2,\ldots,r_k)\),则 \(x=\left(\prod p_i^{r_i/g}\right)^g\),所以 \(x\) 是一个正整数的 \(g\) 次方。

所以可以枚举上文的 \(g\),把每一类不合法方案排除掉,就是答案。

设 \(f(i)\) 表示 \(2\) 到 \(n\) 中 \(i\) 次方数的个数,根据容斥原理,最终答案为:

\[f(1)-\sum_{i\ge1,i\in\text{prime}}f(i)+\sum_{i\ge1,j\ge1,i\ne j,i\in\text{prime},j\in\text{prime}}f(i \cdot j) \cdots \]

即总数减奇数个质数相乘的 \(f\) 值,加偶数个质数相乘的 \(f\) 值。

用莫比乌斯函数 \(\mu\) 可以更简单地表示这个式子:

\[\quad\sum_{i\ge1}\mu(i) \cdot f(i) \]

\(f(i)\) 的计算也很简单:

\[f(i)= \sqrt[i]n - 1 \]

但是这里有个细节问题:如果直接用 c++ 的 pow 函数开方,会出现精度问题,影响答案,这是这道题一个很恶心的地方。具体解决方案如下:

  1. 对于求 \(\sqrt[k]n\),初始用 pow 函数计算出比 \(\sqrt[k]n\) 大的值,具体地,将用 pow 算出的值加 2。

  2. 设刚才算出的值为 \(t\),\(t^k>n\) 则将 \(t\) 减 1。

  3. 求 \(t^k\) 用快速幂,中间过程的变量用 long double 存。

示例代码

#include <bits/stdc++.h>

using namespace std;

typedef long double LD;
typedef long long LL;

const int N = 70;

int prime[N], cnt;
int mu[N];
bool st[N];

void init()
{
	mu[1] = 1;
	for(int i = 2; i < N; i ++ )
	{
		if(!st[i])
		{
			prime[ ++ cnt] = i;
			mu[i] = -1;
		}
		for(int j = 1; j <= cnt && i * prime[j] < N; j ++ )
		{
			int x = i * prime[j];
			st[x] = true;
			if(i % prime[j] == 0)
			{
				mu[x] = 0;
				break;
			}
			mu[x] = -mu[i];
		}
	}
}

LD ksm(LD a, int n)
{
	LD res = 1.0;
	while(n)
	{
		if(n & 1) res *= a;
		a *= a;
		n >>= 1;
	}
	return res;
}

LL solve(int k, LL n)
{
	if(k == 1) return n - 1;
	LL q = (LL)pow(n, 1.0L / k) + 2;
	while(ksm(q, k) > n) q -- ;
	return q - 1;
}

int main()
{
	init();
	int T;
	scanf("%d", &T);
	while(T -- )
	{
		LL n, res = 0;
		scanf("%lld", &n);
		
		for(int i = 1; i <= 60; i ++ )
			if(mu[i])
				res += mu[i] * solve(i, n);
		printf("%lld\n", res);
	}
	return 0;
}

标签:CF1036F,prime,ge1,int,题解,LL,Prime,mu,pow
From: https://www.cnblogs.com/recollect-the-past/p/17981256

相关文章

  • AT_arc098_d Donation 题解
    一道在kruskal重构树上DP的题。首先,捐钱比较难想,可以反过来思考倒着走领钱的思路。显然,在第一次经过一个节点的时候领钱是最优的,对于节点\(i\),令\(c_i=\max\{a_i-b_i,0\}\),若当前的钱数是\(v\),到节点\(i\)的条件是\(v\gec_i\),如果不满足则把\(v\)补充到\(c_i\),同......
  • P5618 SDOI2015 道路修建题解
    题目分析虽然数据范围只有\(n\le60000\),但是完全可以直接用线段树做。首先考虑那种状态的图在左边和右边加入节点和边之后可以连通。容易发现,这种图有这两个性质:至少有一条路径,经过最左端和最右端中的点。所有点至少和最左端和最右端的点连通。于是可以划分成以下几种状态......
  • [ARC155C] Even Sum Triplet 题解
    一道大分类讨论。如果有一个可以交换的段包含奇数,那么你可以把所有奇数移到最左边并任意调整相对顺序,然后回到任意一种有一个可以交换的段包含奇数的状态。这种情况,如果偶数的数量为\(2\),这两个偶数是不能交换相对位置的,有至少\(3\)个偶数就能交换偶数间相对位置。所以只需要......
  • P7618 [COCI2011-2012#2] FUNKCIJA 题解
    看起来比较复杂,但实际上是一个树上dp的模型。因为每一重循环都最多有一个依赖,可以转化为树上的父子关系,于是就形成了一个森林。对于非叶子节点,设\(f_{u,i}\)表示第\(u\)循环变量的值是\(i\)时所有直接或间接依赖于它的循环变量(即以它为根的子树除开它的部分)循环次数,对非......
  • 题解-[ABC288D] Range Add Query
    题目:[ABC288D]RangeAddQuery-洛谷|计算机科学教育新生态(luogu.com.cn) 大意:一些数,选一个区间A(L~R),并再选一个区间B(长度k),这个区间B的每个数加减(加负数=减一个数)一个数,最终使得区间A全部数为0举个例(样例)0.   3-11-2201.  0-4-2-220 (-3)2.  ......
  • 2024 蓝桥杯模拟赛 1 (div1) 题解
    A.把字符串小写转换成大写即可#include<bits/stdc++.h>usingnamespacestd;voidsolve(){strings;cin>>s;for(inti=0;i<s.size();i++){if(s[i]>='a'&&s[i]<='z'){s[i]=(char)(s[i]-'a......
  • 2024 省选联测部分题解
    目录目录R15T1树V图R15T2矩阵缺失题目:R15T3.R15T1树V图原题:SNOI2024D1T1.注意到答案肯定是形如每个连通块选一个点组成,把连通块缩起来后令\(dp_{u,x}\)表示连通块\(u\)选\(x\)的方案数,每次合并子树转移即可.因为只有\(n^2\)个合法点对所以时间复杂度......
  • R语言包安装失败常见问题解决
    更改或指定镜像源出现这个问题很有可能是你现在用的镜像中未纳入这个包,一是可以多换个源试试。如:install.packages('package-name',repos='http://cran.us.r-project.org')或,在Rstudio中可以:或,命令行可直接指定Rstudio:install.packages('package_name',dependencies=TRUE......
  • 【问题解决】Kafka报错 Bootstrap broker x.x.x.x:9092 (id: -1 rack: null) disconne
    【问题解决】Kafka报错Bootstrapbrokerx.x.x.x:9092(id:-1rack:null)disconnected和服务器连接已经断开。可能kafka服务器停止问题复现近日针对某一客户需求开发了一个需要使用Kafka的功能,功能是什么暂且不论,在本地虚机的Kafka连接一切正常遂放到测试服务器上验证功......
  • Kafka【问题 02】KafkaTemplate 报错 Bootstrap broker localhost:9092 (id: -1 rack:
    Kafka【问题02】KafkaTemplate报错Bootstrapbrokerlocalhost:9092(id:-1rack:null)disconnected问题解决1.报错信息主要的报错信息:Connectiontonode-1(localhost/127.0.0.1:9092)couldnotbeestablished.Brokermaynotbeavailable.和Bootstrapbrok......