Codeforces 542D Superhero's Job 数论 哈希表 搜索

原文链接https://www.cnblogs.com/zhouzhendong/p/CF542D.html

题目传送门 - CF542D

题目传送门 - 51Nod1477

题意

  定义公式 $J(x) = \sum_{1 \leq k \leq x 且 k|x 且 \gcd (k,x/k) = 1} k$ 。

  现在给定一个整数 $A$ ,要求有多少正整数 $x$ ,满足 $J(x)=A$ 。

  $x|n$ 表示 $x$ 是 $n$ 的因子。

  $\gcd(a,b) 表示 $a$ 和 $b$ 的最大公约数。

  $1\leq A\leq 10^{12}$

题解

  先考虑如何求 $J(x)$ 。

  由于 $\gcd(k,x/k)=1$ ,所以选出来的 $x$ 和 $x/k$ 的质因数集合没有交集。

  故如果设 $x=\prod p_i^{a_i}$ ,那么 $J(x) = \prod (p_i^{a_i}+1)$ 。

  于是我们考虑 dfs 枚举 A 的因数分解方式,加一些剪枝和优化就可以过了。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL read(){
	LL x=0;
	char ch=getchar();
	while (!isdigit(ch))
		ch=getchar();
	while (isdigit(ch))
		x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return x;
}
const int N=1000005;
LL n;
struct hash_map{
    static const int Ti=233,mod=1<<21;
    int cnt,nxt[mod+1],fst[mod+1];
    LL k[mod+1],v[mod+1];
    int Hash(LL x){
        int v=x&(mod-1);
        return v==0?mod:v;
    }
    void clear(){
        cnt=0;
        memset(fst,0,sizeof fst);
    }
    LL &operator [] (LL x){
        int y=Hash(x);
        for (int p=fst[y];p;p=nxt[p])
            if (k[p]==x)
                return v[p];
        k[++cnt]=x,nxt[cnt]=fst[y],fst[y]=cnt;
        return v[cnt]=0;
    }
}check,use;
LL prime[N],pcnt,vis[N];
void get_prime(){
	memset(vis,0,sizeof vis);
	pcnt=0;
	for (int i=2;i<N;i++){
		if (vis[i])
			continue;
		prime[++pcnt]=i;
		for (int j=i+i;j<N;j+=i)
			vis[j]=1;
	}
}
int Check(LL x){
	if (x<=1)
		return 0;
	for (int i=1;prime[i]*prime[i]<=x&&i<=pcnt;i++)
		if (x%prime[i]==0){
			while (x%prime[i]==0)
				x/=prime[i];
			return x==1?prime[i]:0;
		}
	return x;
}
LL ans=0;
LL fac[N*2],fc=0;
void dfs(LL n,LL *d){
	if (*d>n)
		return;
	if (check[n]&&!use[check[n]])
		ans++;
	if (*d>=n/ *d)
		return;
	for (;*d<n/ *d;d++){
		if (n%*d)
			continue;
		LL &v=use[check[*d]];
		if (!v)
			v=1,dfs(n/ *d,d+1),v=0;
	}
}
int main(){
	get_prime();
	n=read();
	if (n==1)
		return puts("1"),0;
	check.clear();
	for (LL i=1;i*i<=n;i++){
		if (n%i)
			continue;
		LL j=n/i;
		check[i]=Check(i-1);
		check[j]=Check(j-1);
		if (check[i])
			fac[fc++]=i;
		if (i!=j&&check[j])
			fac[fc++]=j;
	}
	use.clear();
	sort(fac,fac+fc);
	fac[fc]=n+1;
	dfs(n,fac);
	printf("%lld",ans);
	return 0;
}

  

Codeforces 542D Superhero's Job 数论 哈希表 搜索

原文地址:https://www.cnblogs.com/zhouzhendong/p/CF542D.html

时间: 2024-10-15 13:47:46

Codeforces 542D Superhero's Job 数论 哈希表 搜索的相关文章

Codeforces 837E Vasya&#39;s Function 数论 找规律

题意:定义F(a,0) = 0,F(a,b) = 1 + F(a,b - GCD(a,b).给定 x 和 y (<=1e12)求F(x,y). 题解:a=A*GCD(a,b) b=B*GCD(a,b),那么b-GCD(a,b) = (B-1)*GCD(a,b),如果此时A和B-1依然互质,那么GCD不变下一次还是要执行b-GCD(a,b).那么GCD什么时候才会变化呢?就是说找到一个最小的S,使得(B-S)%T=0其中T是a的任意一个因子.变形得到:B%T=S于是我们知道S=min(B%T).也

Codeforces 837E Vasya&#39;s Function - 数论

Vasya is studying number theory. He has denoted a function f(a, b) such that: f(a, 0) = 0; f(a, b) = 1 + f(a, b - gcd(a, b)), where gcd(a, b) is the greatest common divisor of a and b. Vasya has two numbers x and y, and he wants to calculate f(x, y).

Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论

Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论 题意 给你一段数,然后小明去猜某一区间内的gcd,这里不一定是准确值,如果在这个区间内改变一个数的值(注意不是真的改变),使得这个区间的gcd是小明所猜的数也算小明猜对.另一种操作就是真的修改某一点的值. 解题思路 这里我们使用线段树,维护区间内的gcd,判断的时候需要判断这个区间的左右子区间的gcd是不是小明猜的数的倍数或者就是小明猜的数,如果是,那么小明猜对了.否则就需要进入这个区间

[CodeForces - 1225D]Power Products 【数论】 【分解质因数】

[CodeForces - 1225D]Power Products [数论] [分解质因数] 题目描述 Time limit 2000 ms Memory limit 524288 kB Source Technocup 2020 - Elimination Round 2 Tags hashing math number theory *1900 Site https://codeforces.com/problemset/problem/1225/D 题面 Example Input 6

【CodeForces】961 F. k-substrings 字符串哈希+二分

[题目]F. k-substrings [题意]给定长度为n的串S,对于S的每个k-子串$s_ks_{k+1}...s_{n-k+1},k\in[1,\left \lceil \frac{n}{2} \right \rceil]$,找到满足[奇数长度][严格子串][同时是前缀和后缀]的最长子串.n<=10^6. [算法]字符串哈希+二分 [题解]任意两个对应子串,它们有一个不变量--它们的中心一定是i和n-i+1.而且固定中心之后,能延伸的最长相等子串是可以二分+哈希得到的. 所以枚举k,二分+

高级哈希表

[转] 这一节涉及数学超级多,各种数论知识,各种不明觉厉! 看了几遍,才勉强看懂一些,所以这 篇稍微简单的介绍着两种hash table, 免得瞎说说错了. 这一讲的主要知识点是: 1. 全域哈希及构造    2. 完美哈希  1. 全域哈希及构造 介绍全域哈希之前,要先讨论一下普通哈希的一个缺点. 举个charles举得那个例子:如果你 和一个竞争对手同时为一家公司做compiler的symbol table, 公司要求你们代码共享 (o(╯□╰)o),你们做好后公司评判的标准就是 你俩互相提

哈希表

哈希表支持的一种最有效的检索方法:散列. 由于计算哈希值和在数组中进行索引都只消耗固定时间,因此哈希表的最大亮点在于他是一种运行时间在常量级的检索方法. 哈希表主要有两种: 1.链式哈希表:将数据存储在桶中的哈希表,每个桶里面都是一个链表,且链表的容量随着冲突的增大而增大.(换句话说就是如果有冲突,会在桶中的链表加上一个存储的值) 2.开地址哈希表:将数据存在表本身,而不是在桶中,他通过各种探查方法来避免冲突. 解决冲突: 不管在以上那种哈希表中,我们的目标是尽可能均匀的分配表中的元素.所以我们

8. 蛤蟆的数据结构进阶八哈希表相关概念

8. 蛤蟆的数据结构进阶八哈希表相关概念 本篇名言:"作家当然必须挣钱才能生活,写作,但是他决不应该为了挣钱而生活,写作.--马克思" 前些笔记我们学习了二叉树相关.现在我们来看下哈希表.这篇先来看下哈希表的相关概念 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47347273 1.  哈希表的概念 哈希表(HashTable)也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构.它通过把关键

哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度

一.哈希表 1.概念 哈希表(Hash Table)也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构.它通过把关键码值映射到哈希表中的一个位置来访问记录,以加快查找的速度.这个映射函数就做散列函数,存放记录的数组叫做散列表. 2.散列存储的基本思路 以数据中每个元素的关键字K为自变量,通过散列函数H(k)计算出函数值,以该函数值作为一块连续存储空间的的单元地址,将该元素存储到函数值对应的单元中. 3.哈希表查找的时间复杂度 哈希表存储的是键值对,其查找的时间复杂度与元素数