题目描述

有$n$个正整数$x_1\sim x_n$,初始时状态均为未选。有$m$个操作,每个操作给定一个编号$i$,将$x_i$的选取状态取反。每次操作后,你需要求出选取的数中有多少个互质的无序数对。


输入格式

第一行两个整数$n,m$。第二行$n$个整数$x_1\sim x_n$。接下来$m$行每行一个整数。


输出格式

$m$行,每行一个整数表示答案。


样例

样例输入:

4 5
1 2 3 4
1
2
3
4
1

样例输出:

0
1
3
5
2


数据范围与提示

对于$20\%$的数据,$n,m\leqslant 1,000$。
对于另外$30\%$的数据,$x_i\leqslant 100$。
对于$100\%$的数据,$n,m\leqslant 200,000$,$x_i\leqslant 500,000$,$1\leqslant i\leqslant n$。


题解

我们先来设三个量:

  $\alpha.s(i)$表示为$i$的倍数的数的个数。

  $\beta.g(i)$表示 $gcd$为$i$的倍数的数个数。

  $\gamma.f(i)$表示$gcd$为$i$的数的个数。

$s(i)$很好就能求出,而$g(i)=\frac{s(i)\times (s(i)-1))}{2}$,但是我们需要的是$f(i)$,该怎么办呢?

显然,$g(i)=\sum \limits_{i|d}f(d)$,那有又什么用呢?

这里就需要用到一个神奇的东东了:第二类莫比乌斯反演(详见信息学奥赛之数学一本通P145中间)。

于是这个式子便变成了:$f(i)=\sum \limits_{i|d}\mu(\frac{d}{i})g(d)$。

现在我们需要考虑的就只有修改操作了,每次插入或删除一个数的时候只要暴力枚举其因数即可。

时间复杂度:$\Theta(m\sqrt{\max x_i})$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
int n,m;
long long a[200001];
long long s[500001],g[500001],f[500001];
long long mu[500001],prime[500001],cnt;
bool vis[200001],v[500001];
long long ans,mx;
void pre_work()
{
mu[1]=1;
for(int i=2;i<=mx;i++)
{
if(!v[i])mu[prime[cnt++]=i]=-1;
for(int j=0;j<cnt&&i*prime[j]<=mx;j++)
{
v[i*prime[j]]=1;
if(i%prime[j])mu[i*prime[j]]=-mu[i];
else{mu[i*prime[j]]=0;break;}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]),mx=max(mx,a[i]);
pre_work();
while(m--)
{
int x,flag;
scanf("%d",&x);
flag=a[x];
if(vis[x])
{
for(int i=1;i*i<=flag;i++)
if(!(flag%i))
{
s[i]--;
ans-=mu[i]*g[i];
g[i]=s[i]*(s[i]-1)/2;
ans+=mu[i]*g[i];
if(flag/i!=i)
{
s[flag/i]--;
ans-=mu[flag/i]*g[flag/i];
g[flag/i]=s[flag/i]*(s[flag/i]-1)/2;
ans+=mu[flag/i]*g[flag/i];
}
}
vis[x]=0;
}
else
{
for(int i=1;i*i<=flag;i++)
if(!(flag%i))
{
s[i]++;
ans-=mu[i]*g[i];
g[i]=s[i]*(s[i]-1)/2;
ans+=mu[i]*g[i];
if(flag/i!=i)
{
s[flag/i]++;
ans-=mu[flag/i]*g[flag/i];
g[flag/i]=s[flag/i]*(s[flag/i]-1)/2;
ans+=mu[flag/i]*g[flag/i];
}
}
vis[x]=1;
}
printf("%lld\n",ans);
}
return 0;
}

rp++

最新文章

  1. Net操作Excel(终极方法NPOI)
  2. 《C#图解教程》读书笔记之五:委托和事件
  3. sql server 2008空间释放
  4. javascript学习笔记-1
  5. IOS--- NavigationBar标题按钮
  6. Yii framework 应用总结小窍门(转)
  7. 上海Uber优步司机奖励政策(1月25日~1月31日)
  8. 使用fastjson前台报406的问题解决方法
  9. Git学习笔记--Git常用命令
  10. Docker之dockerfile
  11. CF 191 div2
  12. ThoughtWorks 面试
  13. 老李推荐:第14章5节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-查询ViewServer运行状态
  14. 并行执行 Job - 每天5分钟玩转 Docker 容器技术(134)
  15. Oracle知识点总结2
  16. Unity3D学习笔记(三十六):Shader着色器(3)- 光照
  17. 第十章 Call 和 Ret 指令
  18. nodeclub models
  19. PendingIntent传递数据注意参数RequestCode和Flag
  20. 双系统IOS\windows7 换成Windows10后果

热门文章

  1. Vue过渡:用Velocity实现JavaScript钩子
  2. sqlalchemy的不区分大小写比较
  3. Java 不被看好前景堪忧?可能是想多了!
  4. Django文件上传下载与富文本编辑框
  5. mint/ubuntu Android Eclipse ADT 简单安装及执行崩溃解决的方法
  6. android 完全退出应用程序(经过严格验证)
  7. tensorflow实现一个神经网络简单CNN网络
  8. Cheatsheet: 2019 07.01 ~ 09.30
  9. 转载一篇别人分享的VSFTPD.CONF的中文解释方便以后查询
  10. 全文检索引擎sphinx 与 Elasticsearch 索引速度对比