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个点 每两个点连一条边(可以为红色或者黑色),求形成的三条边颜色相同的三角形的个数反面考虑这个问题,只 ...
随机推荐
- java学习笔记----java入门
java基础 一.java语言跨平台原理 1.什么是跨平台? 跨平台就是一个软件可以在不同的操作系统中运行,但是不需要对其修改.换句话说,java语言编写的软件在不做修改的情况下就能在不同的系统平台上 ...
- jsp页面中从forEach里向action里面传递其中的一个对象
<c:forEach var="user" items="${users }"> <form action="user_update ...
- 获取JVM的dump文件
获取JVM的dump文件的两种方式 1. JVM启动时增加两个参数: #出现 OOME 时生成堆 dump: -XX:+HeapDumpOnOutOfMemoryError #生成堆文件地址: -XX ...
- 《InsideUE4》UObject(五)类型系统信息收集
在一起!在一起! 引言 前文中我们阐述了类型系统构建的第一个阶段:生成.UHT分析源码的宏标记并生成了包含程序元信息的代码,继而编译进程序,在程序启动的时候,开始启动类型系统的后续构建阶段.而本文我们 ...
- 《Django By Example》第十二章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:第十二章,全书最后一章,终于到这章 ...
- httpclient源码分析之MainClientExec
MainClientExec是HTTP请求处理链中最后一个请求执行环节,负责与另一终端的请求/响应交互,也是很重要的类. 源码版本是4.5.2,主要看execute方法,并在里面添加注释.接着详细说下 ...
- 一键部署ETCD集群脚本
这里使用三个节点,系统版本为CentOS7 # vim deploy-etcd.sh #!/bin/bash set -x set -e #更改这里的IP, 只支持部署3个节点etcd集群 decla ...
- [SinGuLaRiTy] 树形DP专项测试
[SinGuLaRiTy-1015] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 对于所有的题目:Time Limit:1s | Me ...
- SQL SERVER:CASE判断空,错误一例
-----错误判断------------------------------------------------------------------------------------ SELEC ...
- shiro基础学习(三)—shiro授权
一.入门程序 1.授权流程 2.授权的三种方式 (1)编程式: 通过写if/else 授权代码块完成. Subject subject = SecurityUtils.getSubjec ...