题目链接

\(Description\)

给定n个数(\(1\leq a_i\leq 5*10^5\)),每次从这n个数中选一个,如果当前集合中没有就加入集合,有就从集合中删去。每次操作后输出集合中互质的数对个数。

\(Solution1\)

考虑暴力一点,对于要修改的数分解质因数,集合中与它互质的数的个数就是 n-(有1个公共质因数)+(有2个公共质因数)-...

维护一下每种因子(可以是多个因数的积)对应集合中的多少个数就行。

真的好暴力。。但是一个数的质因子大多也就4.5个,so是没问题的。

(\(2*3*5*7*11*13*17>5*10^5\),所以质因子的个数不会超过6个)

唉 一道水题写了一个多小时。。(写法有问题还一直T)

//171ms	4700KB
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 200000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=2e5+5,MAX=5e5+3; int n,Q,A[N],now,have[N],num[MAX],bit[23333],pcnt,P[N],cnt,p[233];
long long Ans;
bool not_P[MAX];
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
void Pre(int n)
{
for(int i=2; i<=n; ++i)
{
if(!not_P[i]) P[++pcnt]=i;
for(int j=1; j<=pcnt && i*P[j]<=n; ++j)
{
not_P[i*P[j]]=1;
if(!(i%P[j])) break;
}
}
for(int i=1,s=0; i<=5000; ++i,s=0)
{
for(int j=0; j<=13; ++j)
if(i>>j & 1) ++s;
bit[i]=s;
}
}
void Div(int x)
{
cnt=0;
for(int i=1; i<=pcnt&&P[i]*P[i]<=x; ++i)//P[i]*P[i]<=x not P[i]<=x!不然就成O(n)的了!
if(!(x%P[i]))
{
p[cnt++]=P[i];
while(!(x%P[i])) x/=P[i];
}
if(x!=1) p[cnt++]=x;
}
void Add(int x,int val)
{
Div(A[x]);
long long ans=~val?now++:--now;//与除x以外的产生影响
for(int i=1; i<(1<<cnt); ++i)
{//枚举因子组合。。
int fac=1;
for(int j=0; j<cnt; ++j)
if(i>>j & 1) fac*=p[j];
if(val==-1) --num[fac];//不能算x本身!
if(bit[i]&1) ans-=num[fac]; else ans+=num[fac];
if(~val) num[fac]++;
}
Ans+=(long long)val*ans;
} int main()
{
n=read(), Q=read(); int mx=0;
for(int i=1; i<=n; ++i) mx=std::max(mx,A[i]=read()), have[i]=-1;
Pre(mx); int x;
while(Q--)
have[x=read()]*=-1, Add(x,have[x]), printf("%I64d\n",Ans);
return 0;
}

\(Solution2\)

  gcd=1。。考虑反演。

  令\(f(d)=\sum_{i=1}^n\sum_{j=1}^n[\gcd(a_i,a_j)=d]\),\(F(d)=\sum_{i=1}^n\sum_{j=1}^n[d\mid\gcd(a_i,a_j)]\),那么$$f(1)=\sum_{i=1}^n\mu(i)F(i)$$

  令\(num[d]\)为含有\(d\)因子的数的个数,则\(F(d)=C_{num[d]}^2\)

  这样每次操作只需要修改其因子的num即可。

//452ms	6600KB(因为要枚举因数而不是只需要枚举质数 有点慢了)
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=2e5+5,MAX=5e5+5; int n,cnt,A[N],P[N],mu[MAX],have[N],num[MAX];
long long Ans;
bool not_P[MAX]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
void Pre(int n)
{
mu[1]=1;
for(int i=2; i<=n; ++i)
{
if(!not_P[i]) P[++cnt]=i, mu[i]=-1;
for(int j=1; j<=cnt&&i*P[j]<=n; ++j)
{
not_P[i*P[j]]=1;
if(i%P[j]) mu[i*P[j]]=-mu[i];
else {mu[i*P[j]]=0; break;}
}
}
}
void Add(int x,int val)
{
for(int i=1; i*i<=x; ++i)//包括1啊→_→
if(!(x%i))
{
Ans-=1ll*mu[i]*num[i]*(num[i]-1)>>1, num[i]+=val;
Ans+=1ll*mu[i]*num[i]*(num[i]-1)>>1;
if(i*i!=x)
{
int j=x/i;
Ans-=1ll*mu[j]*num[j]*(num[j]-1)>>1, num[j]+=val;
Ans+=1ll*mu[j]*num[j]*(num[j]-1)>>1;
}
}
} int main()
{
n=read(); int Q=read(),mx=0;
for(int i=1; i<=n; ++i) mx=std::max(mx,A[i]=read()), have[i]=-1;
Pre(mx); int x;
while(Q--)
have[x=read()]*=-1, Add(A[x],have[x]), printf("%I64d\n",Ans);
return 0;
}

Codeforces.547C.Mike and Foam(容斥/莫比乌斯反演)的更多相关文章

  1. hdu4135-Co-prime & Codeforces 547C Mike and Foam (容斥原理)

    hdu4135 求[L,R]范围内与N互质的数的个数. 分别求[1,L]和[1,R]和n互质的个数,求差. 利用容斥原理求解. 二进制枚举每一种质数的组合,奇加偶减. #include <bit ...

  2. cf#305 Mike and Foam(容斥)

    C. Mike and Foam time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  3. 【二分+容斥+莫比乌斯反演】BZOJ2440 完全平方数

    Description 求第k个没有完全平方因子的数,k<=1e9. Solution 这其实就是要求第k个µ[i](莫比乌斯函数)不为0的数. 然而k太大数组开不下来是吧,于是这么处理. 二分 ...

  4. 51nod 1355 - 斐波那契的最小公倍数(Min-Max 容斥+莫比乌斯反演)

    vjudge 题面传送门 首先我们知道斐波那契数列的 lcm 是不太容易计算的,但是它们的 gcd 非常容易计算--\(\gcd(f_x,f_y)=f_{\gcd(x,y)}\),该性质已在我的这篇博 ...

  5. cf900D. Unusual Sequences(容斥 莫比乌斯反演)

    题意 题目链接 Sol 首先若y % x不为0则答案为0 否则,问题可以转化为,有多少个数列满足和为y/x,且整个序列的gcd=1 考虑容斥,设\(g[i]\)表示满足和为\(i\)的序列的方案数,显 ...

  6. bzoj 2005 & 洛谷 P1447 [ Noi 2010 ] 能量采集 —— 容斥 / 莫比乌斯反演

    题目:bzoj 2005 https://www.lydsy.com/JudgeOnline/problem.php?id=2005   洛谷 P1447 https://www.luogu.org/ ...

  7. codeforces 547c// Mike and Foam// Codeforces Round #305(Div. 1)

    题意:给出数组arr和一个空数组dst.从arr中取出一个元素到dst为一次操作.问每次操作后dst数组中gcd等于1的组合数.由于数据都小于10^6,先将10^6以下的数分解质因数.具体来说从2开始 ...

  8. HDU 5942 Just a Math Problem 容斥 莫比乌斯反演

    题意:\( g(k) = 2^{f(k)} \) ,求\( \sum_{i = 1}^{n} g(i) \),其中\( f(k)\)代表k的素因子个数. 思路:题目意思很简单,但是着重于推导和简化,这 ...

  9. BZOJ4833: [Lydsy1704月赛]最小公倍佩尔数(min-max容斥&莫比乌斯反演)(线性多项式多个数求LCM)

    4833: [Lydsy1704月赛]最小公倍佩尔数 Time Limit: 8 Sec  Memory Limit: 128 MBSubmit: 240  Solved: 118[Submit][S ...

随机推荐

  1. [转]C++ 取代switch的三种方法

    1.常规switch enum EnumType { enumOne, enumTwo, enumThree }; void showMessage(int type) { switch(type) ...

  2. 使用Picker的时候,让input输入框使用焦点,手机键盘不弹出

    $("#address").click(function(){ document.activeElement.blur(); })

  3. OpenStack Benchmark - Rally

    作为以基于OpenStack的云平台的基准测试工具 -- Rally, 其功能不仅是测试云的性能&&稳定性, 还可以安装OpenStack,以及以良好的表现形式(web 页面)展现测试 ...

  4. centos 升级linux内核

    =============================================== 2018/1/14_第1次修改                       ccb_warlock == ...

  5. Failed to load class "org.slf4j.impl.StaticLoggerBinder"

    调试程序出现如下错误: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".SLF4J: Default ...

  6. Shell编程学习2--命令大全

    Linux中有很多的命令,这些命令可分分为10类(具体参见[1]): 1) 文件管理; 2) 文档编辑; 3) 文件传输; 4) 磁盘管理; 5) 磁盘维护; 6) 网络通讯; 7) 系统管理; 8) ...

  7. java基础70 负责静态的网页制作语言XML(网页知识)

    HTML:负责网页结构的CSS:负责网页的样式(美观)JavaScript:负责客户(浏览器)端与用户进行交互 1.HTML语言的特点 1.由标签组成    2.语法结构松散     3.大小写不区分 ...

  8. 客户端使用less方法

    <link rel="stylesheet/less" type="text/css" href="/css/style.less"& ...

  9. Luogu P1566 【加等式】

    看到这道题,我们首先注意到“找出其所有的加等式的个数”,自然地考虑运用计数DP求出若干数相加的和的个数 考虑将每个元素排序后DP处理若干数相加的和的个数 用f[i]表示 对于一个数a[i],对于前i- ...

  10. (四)SpringMvc文件上传

    第一节:SpringMvc单文件上传 第二节:SpringMvc多文件上传