题目链接

\(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. 如何在ie6/ie7/ie8中实现iframe背景透明

    最近做了一个项目,涉及到ie8iframe背景透明的问题,做了老半天,才把它搞定的,现在把我的经历贴出来和大家分享: 众所周知的根据W3C CSS 2.1 规范规定,''''background-co ...

  2. Strusts2笔记4--类型转换器

    类型转换器: Struts2默认情况下可以将表单中输入的文本数据转换为相应的基本数据类型.这个功能的实现,主要是由于Struts2内置了类型转换器.这些转换器在struts-default.xml中可 ...

  3. web项目启动首页能访问接口报404

    这个问题如果控制台没有报错,然后看一下日志,看看spring容器是否加载: 如果是一直卡在这里了,多半是resources文件下的配置有问题,或者是resources目录不是源文件,工具无法识别 我遇 ...

  4. 【codeforces】940F题解

    CF Round #466的最后一题,颇有难度,正解是带修改莫队算法. [题意] 给定一个长度为\(n\)的数组\(a\),并且要求执行\(q\)个操作,有两种不同的操作: ①询问一个区间\([l,r ...

  5. CertUtil.exe被利用来下载恶意软件

    1.前言 经过国外文章信息,CertUtil.exe下载恶意软件的样本. 2.实现原理 Windows有一个名为CertUtil的内置程序,可用于在Windows中管理证书.使用此程序可以在Windo ...

  6. ADB常用命令(二)

    参考  http://adbshell.com/commands 常用命令 查看adb 版本 adb version 打印所有附加模拟器/设备的列表 adb devices 设备序列号 adb get ...

  7. Windows Phone 8 获取设备名称

    通过使用Microsoft.Phone.Info.DeviceStatus类,我们可以获取设备的一些信息,如设备厂商,设备名称等.通过Microsoft.Phone.Info.DeviceStatus ...

  8. python基础学习之路No.3 控制流if,while,for

    在学习编程语言的过程中,有一个很重要的东西,它就是判断,也可以称为控制流. 一般有if.while.for三种 ⭐if语句 if语句可以有一个通俗的解释,如果.假如 如果条件1满足,则…… 如果条件2 ...

  9. java IO流的继承体系和装饰类应用

    java IO流的设计是基于装饰者模式&适配模式,面对IO流庞大的包装类体系,核心是要抓住其功能所对应的装饰类. 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的 ...

  10. Python之Selenium的爬虫用法

    Selenium 2,又名 WebDriver,它的主要新功能是集成了 Selenium 1.0 以及 WebDriver(WebDriver 曾经是 Selenium 的竞争对手).也就是说 Sel ...