Codeforces 585E. Present for Vitalik the Philatelist(容斥)
好题!学习了好多
写法①:
先求出gcd不为1的集合的数量,显然我们可以从大到小枚举计算每种gcd的方案(其实也是容斥),或者可以直接枚举gcd然后容斥(比如最大值是6就用2^cnt[2]-1+3^cnt[3]-1-(6^cnt[6]-1),cnt[x]表示x的倍数的个数),用容斥计算的话可以发现系数是莫比乌斯函数的相反数,就可以线性筛了。下面会记录一种O(MAX*ln(MAX))的筛法...求cnt的话可以选择直接枚举倍数计算O(MAX*ln(MAX))或者分解质因数,因为1e7内最多有8个不同质因子,求出所有质因子再枚举子集给cnt加上贡献。
然后枚举每一个数计算它对答案的贡献,就是gcd不为1的集合的数量里去掉这个数的因数的贡献,分解质因数之后一个一个去掉即可。
这种写法就不写代码啦~(其实写了但是写炸了懒得调了
O(MAX*ln(MAX))莫比乌斯函数筛:
miu[]=;
for(int i=;i<=mx;i++)
for(int j=i<<;j<=mx;j+=i) miu[j]-=miu[i];
写法②:
这是一种更简单的写法,尝试把上面统计数量后计算每个数的贡献这两个过程合二为一。
考虑去掉一个数的因数对答案的贡献怎么更简单地做,可以发现一个数的所有因数的cnt里都有这个数的贡献,所以我们实际上可以在统计答案的时候直接计算所有数的贡献顺便去掉这个数的贡献,也就是以下的公式:

中间部分是gcd为x的时候的方案数,右边是gcd为x时对此式子有贡献的数的数量。
我们求莫比乌斯函数的时候用上上面的O(MAX*ln(MAX))版筛法就可以把代码长度做到极短了。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#define MOD(x) ((x)>=mod?(x)-mod:(x))
using namespace std;
const int maxn=, maxm=1e7+, inf=1e9+, mod=1e9+;
int n, x, mx, ans;
int mi[maxn], cnt[maxm], miu[maxm];
void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-' && (f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
int main()
{
read(n); mi[]=; for(int i=;i<=n;i++) mi[i]=(1ll*mi[i-]<<)%mod;
for(int i=;i<=n;i++) read(x), cnt[x]++, mx=max(mx, x);
miu[]=;
for(int i=;i<=mx;i++)
{
for(int j=i<<;j<=mx;j+=i) miu[j]-=miu[i], cnt[i]+=cnt[j];
if(!cnt[i] || !miu[i]) continue;
int delta=1ll*miu[i]*(mi[cnt[i]]-)%mod*(cnt[i]-n)%mod;
delta=MOD(delta+mod); ans=MOD(ans+delta);
}
printf("%d\n", ans);
}
写法③:
是在写法②的基础上的,可以省去求莫比乌斯函数的过程。
可以倒着枚举数i,一般可以较为简单的计算i的倍数的总贡献,然后删去i的倍数(此时不包括i)的贡献(此时倍数的贡献已经计算好了)来得到i的贡献。注意!!!这里i的答案指的是如果计算i的话答案是多少,但实际上可能是需要减去的,它会被它的因数减去而得到它的因数的答案。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#define MOD(x) (x>=mod?(x)-mod:(x))
using namespace std;
const int maxn=, inf=1e9, maxm=1e7+, mod=1e9+;
int n, x, mx, anss;
int ans[maxm], mi[maxn], cnt[maxm];
inline void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-'&&(f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
int main()
{
read(n);
for(int i=;i<=n;i++) read(x), cnt[x]++, mx=max(mx, x);
mi[]=; for(int i=;i<=n;i++) mi[i]=(1ll*mi[i-]<<)%mod;
for(int i=mx;i>=;i--)
{
int sum=cnt[i];
for(int j=i<<;j<=mx;j+=i) sum+=cnt[j], ans[i]=MOD(ans[i]-ans[j]+mod);
ans[i]+=1ll*(mi[sum]-)*(n-sum)%mod; ans[i]=MOD(ans[i]);
anss=MOD(anss+ans[i]);
}
printf("%d\n", anss);
}
Codeforces 585E. Present for Vitalik the Philatelist(容斥)的更多相关文章
- Codeforces 585E - Present for Vitalik the Philatelist(简单莫反+狄利克雷前缀和)
Codeforces 题目传送门 & 洛谷题目传送门 一道不算太难的 D1E 罢--虽然我不会做/kk u1s1 似乎这场 Div1 挺水的?F 就是个 AC 自动机板子还被评到了 3k2-- ...
- 【CF 585E】 E. Present for Vitalik the Philatelist
E. Present for Vitalik the Philatelist time limit per test 5 seconds memory limit per test 256 megab ...
- 【CodeForces】585 E. Present for Vitalik the Philatelist
[题目]E. Present for Vitalik the Philatelist [题意]给定n个数字,定义一种合法方案为选择一个数字Aa,选择另外一些数字Abi,令g=gcd(Ab1...Abx ...
- CF585E. Present for Vitalik the Philatelist [容斥原理 !]
CF585E. Present for Vitalik the Philatelist 题意:\(n \le 5*10^5\) 数列 \(2 \le a_i \le 10^7\),对于每个数\(a\) ...
- 「CF585E」 Present for Vitalik the Philatelist
「CF585E」 Present for Vitalik the Philatelist 传送门 我们可以考虑枚举 \(S'=S\cup\{x\}\),那么显然有 \(\gcd\{S'\}=1\). ...
- CF 585 E Present for Vitalik the Philatelist
CF 585 E Present for Vitalik the Philatelist 我们假设 $ f(x) $ 表示与 $ x $ 互质的数的个数,$ s(x) $ 为 gcd 为 $ x $ ...
- CF585E:Present for Vitalik the Philatelist
n<=500000个2<=Ai<=1e7的数,求这样选数的方案数:先从其中挑出一个gcd不为1的集合,然后再选一个不属于该集合,且与该集合内任意一个数互质的数. 好的统计题. 其实就 ...
- Codeforces Round #345 (Div. 1) A - Watchmen 容斥
C. Watchmen 题目连接: http://www.codeforces.com/contest/651/problem/C Description Watchmen are in a dang ...
- CodeForces 559C Gerald and Gia (格路+容斥+DP)
CodeForces 559C Gerald and Gia 大致题意:有一个 \(N\times M\) 的网格,其中有些格子是黑色的,现在需要求出从左上角到右下角不经过黑色格子的方案数(模 \(1 ...
随机推荐
- 关于Eclipse在servlet中连接数据库时出现驱动加载失败的解决
问题:在队友发来的项目中想将他获取到的数据通过数据库储存,出现驱动加载失败问题 解决:首先百度了下相关情况,大多数都是说下载mysql-connector-java-5.1.39-bin.jar包,然 ...
- dubbo SpringContainer
dubbo SpringContainer Spring启动类容器 SPI service provider interfaces 服务提供借口 Singleton 单例 ThreadSafe 线程安 ...
- 用gdb调试程序(Linux环境)
一般来说,GDB主要帮忙你完成下面四个方面的功能: 1.启动你的程序,可以按照你的自定义的要求随心所欲的运行程序. 2.可让被调试的程序在你所指定的调置的断点处停住.(断点可以是条件表达式) ...
- 【转】PHPCMS v9 自定义表单添加验证码验证
1. 在 \phpcms\templates\default\formguide\show.html 中添加验证码显示 <input type="text" id=&quo ...
- PytorchZerotoAll学习笔记(二)--梯度下降之手动求导
梯度下降算法: 待优化的损失值为 loss,那么我们希望预测的值能够很接近真实的值 y_pred ≍ y_label 我们的样本有n个,那么损失值可以由一下公式计算得出: 要使得los ...
- Python20-Day02
1.数据 数据为什么要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同类型的数据表示: 数据类型 数字(整形,长整形,浮点型,复数),字符串,列表,元组,字典,集合 2.字符串 1.按索引取 ...
- socket发送文字、图片、文件---基于python实现
socket官方文档:https://docs.python.org/2/library/socket.html socket中文详细介绍:http://blog.csdn.net/rebelqsp/ ...
- USACO 1.2.2 Transformations 方块转换
Description 一块N x N(1<=N<=10)正方形的黑白瓦片的图案要被转换成新的正方形图案.写一个程序来找出将原始图案按照以下列转换方法转换成新图案的最小方式: 1:转90度 ...
- 冲刺ing-2
第二次Scrum冲刺 队员完成的任务 队员 完成任务 吴伟华 分配任务 蔺皓雯 编写博客,查阅资料 蔡晨旸 查阅资料 曾茜 暂无 鲁婧楠 暂无 杨池宇 暂无 成员遇到的问题 队员 问题 吴伟华 暂无 ...
- jQuery之数组处理函数
摘要:$.each,$.grep,$.map,$.merge,$.inArray,$.unique,$.makeArray 1. $.each(array, [callback]) 遍历[常用] 解释 ...