Codeforces 548 E Mike ans Foam (與質數相關的容斥多半會用到莫比烏斯函式)
題面
Description
Mike is a bartender at Rico's bar. At Rico's, they put beer glasses in a special shelf. There are n kinds of beer at Rico's numbered from 1 to n. i-th kind of beer has *a**i* milliliters of foam on it.
Maxim is Mike's boss. Today he told Mike to perform q queries. Initially the shelf is empty. In each request, Maxim gives him a number x
After each query, Mike should tell him the score of the shelf. Bears are geeks. So they think that the score of a shelf is the number of pairs (i, j) of glasses in the shelf such that i
Mike is tired. So he asked you to help him in performing these requests.
Input
The first line of input contains numbers n and q (1 ≤ n, q ≤ 2 × 105), the number of different kinds of beer and number of queries.
The next line contains n
The next q lines contain the queries. Each query consists of a single integer integer x(1 ≤ x ≤ n), the index of a beer that should be added or removed from the shelf.
Output
For each query, print the answer for that query in one line.
Examples
input | output |
---|---|
5 6 |
1 2 3 4 6
1
2
3
4
5
1 | 0
1
3
5
6
2 |
題目分析
如題,用\(\mu\)進行容斥即可。
程式碼實現
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<iomanip>
#include<cstdlib>
#define MAXN 0x7fffffff
typedef long long LL;
const int N=500005;
using namespace std;
inline int Getint(){register int x=0,f=1;register char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}return x*f;}
int prime[N],mu[N];
bool vis[N],chk[200005];
int a[200005],cnt[N];
int main(){
mu[1]=1;
for(int i=2;i<=5e5;i++){
if(!vis[i])prime[++prime[0]]=i,mu[i]=-1;
for(int j=1;j<=prime[0]&&i*prime[j]<=5e5;j++){
vis[i*prime[j]]=1;
if(i%prime[j]==0)break;
mu[i*prime[j]]=-mu[i];
}
}
int n=Getint(),q=Getint();
for(int i=1;i<=n;i++)a[i]=Getint();
LL ans=0;
for(int j=1;j<=q;j++){
int x=Getint(),ret=0;
if(!chk[x]){
chk[x]=1,x=a[x];
for(int i=1,lim=sqrt(x);i<=lim;i++){
if(x%i==0){
ret+=mu[i]*cnt[i],cnt[i]++;
if(i*i!=x)ret+=mu[x/i]*cnt[x/i],cnt[x/i]++;
}
}
ans+=ret;
}else{
chk[x]=0,x=a[x];
for(int i=1,lim=sqrt(x);i<=lim;i++){
if(x%i==0){
cnt[i]--,ret+=mu[i]*cnt[i];
if(i*i!=x)cnt[x/i]--,ret+=mu[x/i]*cnt[x/i];
}
}
ans-=ret;
}
cout<<ans<<'\n';
}
return 0;
}
/*
8 8
77770 436260 150552 164101 453308 1 1 329637
1 2 3 4 5 6 7 8
*/