HDU 1695 GCD 容斥原理/莫比乌斯反演

2024-06-12 11:38

本文主要是介绍HDU 1695 GCD 容斥原理/莫比乌斯反演,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题意:

给你两个区间[a,b],[c,d],还有一个k。让你从区间[a,b]中找出x,[c,d]中找出y,问共有多少组(x,y)使得gcd(x,y)=k。

(x,y)和(y,x)算一组。

思路:

参考:http://blog.csdn.net/yang_7_46/article/details/9072533

容斥。


普通容斥:

*如果gcd(x,y)=k,则gcd(x/k,y/k)=1。那么对于两个区间来说,我们都默认进行了b = b/k,d = d/k操作。(a,c固定为1)。(这样做并不会使得组数遗漏)

因为(x,y)和(y,x)只算一组,因此在容斥过程中,我们要保证x < y,这样才不会重复计算。

剩下就是容斥的过程,可以戳这里。

其它一些细节要自己处理一下,例如b = 1或者d = 1的时候。


莫比乌斯反演:

莫比乌斯资料:http://blog.csdn.net/acdreamers/article/details/8542292

定义f(n):gcd(x, y)为n的方案数。

定义F(n):gcd(x, y)是n的倍数的方案数。

则我们要求的就是f(1)。默认b < d,并且都已经除以k。

F(n) = (b/n)*(d/n);

套用莫比乌斯公式即可。


code(普通容斥):

#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;const int MAXN = 1e5+5;
typedef long long LL;int a, b, c, d, k;
bool isp[MAXN+5];
vector <int> vec[MAXN+5];void prime()
{memset(isp, false, sizeof(isp));for(int i = 2;i <= MAXN; i++){if(!isp[i]){vec[i].push_back(i);for(int j = i*2; j <= MAXN; j += i){isp[j] = true;vec[j].push_back(i);}}}
}
LL calc(int t, int p)
{LL ret, v = 1;int cnt = 0;for(int i = 0;i < vec[t].size(); i++){if((1<<i)&p){cnt++;v *= vec[t][i];}}if(v == 0) return 0;ret = (LL)(d-t)/v;if(cnt%2 == 0) ret = -ret;return ret;
}void solve()
{//tepan 1LL res = d;for(int i = 2;i <= b; i++){res += d-i;for(int j = 1;j < (1<<vec[i].size()); j++)res -= calc(i, j);}printf("%I64d\n", res);
}int main()
{prime();int T, cas = 0;scanf("%d", &T);while(T--){scanf("%d%d%d%d%d", &a, &b, &c, &d, &k);printf("Case %d: ", ++cas);if(k == 0){puts("0");continue;}b /= k, d /= k;if(b > d) swap(b, d);if(b == 0 || d == 0)puts("0");else solve();}return 0;
}

 code(莫比乌斯反演):

#include <bits/stdc++.h>
using namespace std;const int N = 1e5+5;
typedef long long LL;int b, d, k;
int prime[N], cnt;
int mu[N];
bool vis[N];
void Mobius() {mu[1] = 1;cnt = 0;for(int i = 2;i < N; i++) {if(!vis[i]) {mu[i] = -1;prime[cnt++] = i;}for(int j = 0;j < cnt; j++) {if(i*prime[j] >= N) break;vis[i*prime[j]] = true;if(i%prime[j] != 0)mu[i*prime[j]] = -mu[i];else {mu[i*prime[j]] = 0;break;}}}
}int main() {Mobius();int T, cas = 0;scanf("%d", &T);while(T--) {scanf("%*d%d%*d%d%d", &b, &d, &k);printf("Case %d: ", ++cas);if(k == 0) {puts("0");continue;}b /= k, d /= k;if(b > d) swap(b, d);LL ans = 0;for(int i = 1;i <= b; i++)ans += 1ll*mu[i]*(b/i)*(d/i);LL tmp = 0;for(int i = 1;i <= b; i++)tmp += 1ll*mu[i]*(b/i)*(b/i);printf("%I64d\n", ans-tmp/2);}return 0;
}



这篇关于HDU 1695 GCD 容斥原理/莫比乌斯反演的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1054115

相关文章

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2093 考试排名(sscanf)

模拟题。 直接从教程里拉解析。 因为表格里的数据格式不统一。有时候有"()",有时候又没有。而它也不会给我们提示。 这种情况下,就只能它它们统一看作字符串来处理了。现在就请出我们的主角sscanf()! sscanf 语法: #include int sscanf( const char *buffer, const char *format, ... ); 函数sscanf()和

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s