Codeforces 803F Coprime Subsequences (容斥)
Link:http://codeforces.com/contest/803/problem/F
题意:给n个数字,求有多少个GCD为1的子序列。
题解:容斥!比赛时能写出来真是炒鸡开森啊!
num[i]: 有多少个数字是 i 的倍数。
所有元素都是1的倍数的序列有:$2^n-1$个。先把$2^n-1$设为答案
所有元素都是质数的倍数的序列有:$\sum 2^{num[p_1]} - 1$个,这些序列不存在的,得从答案中减去。
所有元素都是两质数之积的倍数的序列有:$\sum 2^{num[p_1*p_2]} - 1$个,这些序列两次扫黄都在现
场,我们应减一次,但实际减了两次,多减了一次,所以要加回到答案中。
然后考虑,所有元素都是3,4,5......个质数之积的倍数的序列。
依次类推。于是就可以容斥了。
PS: 要先预处理好一个数字,能被拆成几个素数之积。而且同一个素数不能出现两次或以上。
【不优雅の】code:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
const int MAXN = 100000+10;
const int MAXM = 100000+10;
ll prime[MAXN+1];
ll ct[MAXN], sgn[MAXN];
ll n, a[MAXN], bad[MAXN];
void getPrim()
{
memset(sgn, 1, sizeof(sgn));
memset(prime, 0, sizeof(prime));
for(int i=2;i<=MAXN;i++)
{
if(!prime[i]){
prime[++prime[0]] = i;
}
for(int j=1;(j<=prime[0])&&(prime[j]<=(MAXN/i));j++)
{
prime[prime[j]*i] = 1;
if(i%prime[j]==0) break;
}
}
} void getFactor(ll x)
{
ll cnt = 0, i;
ll tmp = x;
for(i = 1; prime[i] * prime[i] <=tmp ;i++)
{
if(tmp % prime[i] == 0)
{
int c = 0;
while(tmp % prime[i] == 0)
{
c ++;
tmp /= prime[i];
}
if(c >= 2)
{
bad[x] = 1;
return;
}
cnt ++;
}
}
if(tmp!=1)
{
cnt ++;
}
ct[x] = cnt;
} const ll MOD = 1000000007;
ll mpow(ll a, ll n)
{
ll ret = 1;
while(n)
{
if(n & 1)
{
ret = (ret * a);
ret %= MOD;
}
a = a * a % MOD;
n >>= 1;
}
return ret;
} ll num[MAXN];
int main()
{
getPrim();
for(int i=1;i<MAXN;i++)
{
getFactor(i);
}
scanf("%lld", &n);
for(int i=1;i<=n;i++)
{
scanf("%lld", &a[i]);
for(ll j=1;j*j<=a[i];j++)
{
if(a[i]%j==0)
{
if(j*j!=a[i]) num[a[i]/j] ++;
num[j] ++;
}
}
}
ll ans = 0;
for(int i=2;i<MAXN;i++)
{
if(num[i]>0 && ct[i]>0 && !bad[i])
{
//cout << i << " " << num[i] << " " << ct[i] << endl;
ans += (ll)( (ct[i]%2==1)?(1):(-1) ) * (mpow(2, num[i])-1);
ans %= MOD;
}
}
ans = (mpow(2, n) - ans + MOD) % MOD;
cout << (ans-1+MOD)%MOD << endl;
}
官方题解提到了莫比乌斯函数,最终答案的表示为$\sum\limits_{i=1}^{1e5} µ(i)(2^{num[i]}-1)$
套了下KuangBin巨巨的模板。重写了遍。
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const int NICO = 100000+2;
const int MOD = 1000000000 + 7;
LL n, a[NICO], cnt[NICO], po[NICO], mo[NICO];
bool chk[NICO];int prime[NICO];
void init()
{
po[0] = 1, mo[1] = 1;
for(int i=1;i<NICO;i++) po[i] = 2*po[i-1]%MOD;
memset(chk, 0, sizeof(chk));
int tot = 0;
for(int i=2;i<NICO;i++)
{
if(!chk[i])
{
prime[tot++] = i;
mo[i] = -1;
}
for(int j=0;j<tot;j++)
{
if(i*prime[j]>=NICO) break;
chk[i*prime[j]] = 1;
if(i%prime[j] == 0)
{
mo[i*prime[j]] = 0;
break;
} else {
mo[i*prime[j]] = -mo[i];
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j*j<=a[i];j++)
{
if(a[i]%j) continue;
if(j*j != a[i]) cnt[a[i]/j] ++;
cnt[j] ++;
}
}
} int main()
{
scanf("%lld", &n);
for(int i=1;i<=n;i++) scanf("%lld", &a[i]);
LL ans = 0; init();
for(int i=1;i<NICO;i++)
{
ans = (ans + mo[i] * (po[cnt[i]]-1) )% MOD;
}
cout << (ans+1000LL*MOD)%MOD << endl;
}
Codeforces 803F Coprime Subsequences (容斥)的更多相关文章
- Codeforces 803F - Coprime Subsequences(数论)
原题链接:http://codeforces.com/contest/803/problem/F 题意:若gcd(a1, a2, a3,...,an)=1则认为这n个数是互质的.求集合a中,元素互质的 ...
- CodeForces 803F Coprime Subsequences
$dp$. 记$dp[i]$表示$gcd$为$i$的倍数的子序列的方案数.然后倒着推一遍减去倍数的方案数就可以得到想要的答案了. #include <iostream> #include ...
- Codeforces 100548F - Color (组合数+容斥)
题目链接:http://codeforces.com/gym/100548/attachments 有n个物品 m种颜色,要求你只用k种颜色,且相邻物品的颜色不能相同,问你有多少种方案. 从m种颜色选 ...
- HDU 4135 Co-prime(容斥+数论)
Co-prime Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- HDU 4135:Co-prime(容斥+二进制拆分)
Co-prime Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- 题解报告:hdu 4135 Co-prime(容斥定理入门)
Problem Description Given a number N, you are asked to count the number of integers between A and B ...
- HDU 4135 Co-prime(容斥:二进制解法)题解
题意:给出[a,b]区间内与n互质的个数 思路:如果n比较小,我们可以用欧拉函数解决,但是n有1e9.要求区间内互质,我们可以先求前缀内互质个数,即[1,b]内与n互质,求互质,可以转化为求不互质,也 ...
- Codeforces 920G(二分+容斥)
题意: 定义F(x,p)表示的是一个数列{y},其中gcd(y,p)=1且y>x 给出x,p,k,求出F(x,p)的第k项 x,p,k<=10^6 分析: 很容易想到先二分,再做差 然后问 ...
- Hdu 5072 Coprime(容斥+同色三角形)
原题链接 题意选出三个数,要求两两互质或是两两不互质.求有多少组这样的三个数. 分析 同色三角形n个点 每两个点连一条边(可以为红色或者黑色),求形成的三条边颜色相同的三角形的个数反面考虑这个问题,只 ...
随机推荐
- pymysql使用心得记录
-----------更新日志 16.7.29------------- (该记录对应文章<豆瓣电影Top250基本信息抓取 >) 折腾了将近两天才把mysql数据库功能给实现了. 经过 ...
- 自适应滤波——线性预测(LPC)
作者:桂. 时间:2017-03-26 10:12:07 链接:http://www.cnblogs.com/xingshansi/p/6621914.html 声明:欢迎被转载,不过记得注明出处哦 ...
- java的特点跨平台原理以及JDK的安装
终于开始了期待已久的java,了解java首先要了解下计算机语言的发展历史 机器语言--->汇编语言--->--->高级语言(面向过程的语言和面向对象的语言) 机器语言 每一个计算机 ...
- 如何查看sql server端口号
通过sql server配置管理器-->sql server网络配置-->选择-->通过右侧选择TCP/IP(已启用)-->查看属性 还可以通过sql语句查看: exec sy ...
- 核心模块Path
核心模块Path 作用:用于帮助程序员来操作硬盘上的路径. 核心模块注意点:当引用核心模块的时候直接require('模块名'),不需要加任何路径或者后缀. Path中的常用API: dirname( ...
- codeforces 372E. Drawing Circles is Fun
tags:[圆の反演][乘法原理][尺取法]题解:圆の反演:将过O点的圆,映射成不过O的直线,相切的圆反演出来的直线平行.我们将集合S中的点做反演变换:(x,y)->(x/(x^2+y^2), ...
- 【转】Flash字体嵌入方法
原文链接:http://www.cnblogs.com/ddw1997/archive/2011/11/13/2247546.html 一.如果使用flash cs5.5 1.先新建一个字体fla文件 ...
- 不忘初心 --- 重读<<The C Programming Language>>
这篇文章应该发布在好几年前,2011年计算机界大师Dennis Ritchie仙逝,那时对大师的映象还停留在大一刚学编程时:Unix的合作开发者,C语言的发明人.通过网上的纪念文章<<Un ...
- E/MediaPlayer: Should have subtitle controller already set
原文链接:http://stackoverflow.com/questions/20087804/should-have-subtitle-controller-already-set-mediapl ...
- Vuex随笔
最近在项目中使用到了vuex,但是在配合vue使用时,也还是遇到了不少的问题,最终还是解决了问题,因此写一篇随笔来记录期间遇到的问题吧 项目概要: Vuex中所储存的的状态如下: Vue中:有一个ta ...