C. Mike and Foam
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

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 ai 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. If beer number x is already in the shelf, then Mike should remove it from the shelf, otherwise he should put it in the shelf.

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 < j and where is the greatest common divisor of numbers a and b.

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 space separated integers, a1, a2, ... , an (1 ≤ ai ≤ 5 × 105), the height of foam in top of each kind of beer.

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.

Sample test(s)
Input
5 6
1 2 3 4 6
1
2
3
4
5
1
Output
0
1
3
5
6
2
 #include<vector>
#include<stdio.h>
#include<string.h>
#include<algorithm>
typedef long long ll ;
const int M = 5e5 + ;
int n , q ;
int a[M] ;
int dp[M] , cnt[M] ;
bool vis[M] ;
std::vector <int> g[M] ; void table ()
{
dp[] = ;
for (int i = ; i < M ; i ++) {
if (dp[i]) g[i].push_back(i) ;
for (int j = i + i ; j < M ; j += i ) {
if (dp[i]) g[j].push_back(i) ;
dp[j] -= dp[i] ;
}
}
} int main ()
{
//freopen ("a.txt" , "r" , stdin ) ;
table () ;
scanf ("%d%d" , &n , &q) ;
for (int i = ; i <= n ; i ++) scanf ("%d" , &a[i]) ;
ll ans = ;
while (q --) {
int x ;
scanf ("%d" , &x) ;
if (vis[x]) {
for (int i : g[ a[x] ]) ans -= 1ll * dp[i] * (-- cnt [i]) ;
} else {
for (int i : g[ a[x] ]) {
ans += 1ll * dp[i] * (cnt[i] ++) ;
}
}
vis[x] ^= ;
printf ("%I64d\n" , ans) ;
}
return ;
}

第一次接触容斥问题,但已接触过默比乌斯反演。orz

容斥简单来说是这样的:

有n个群学生选了A课程,B课程,C课程。其中选了A课程的为集合{A},B的为集合{B}人,C的为集合{C}。

那么n = A + B + C - A&B - B&C - A&C + A&B&C ;

通过观察,我们可以yy出这样的性质:

奇数集合:A , B , C , A&B&C …… 指奇数个集合形成的交集。

偶数集合:A&B , B&C , A&C …… 指偶数个集合形成的交集。

so n = sum(奇数集合) - sum(偶数集合);

再回到这道题目上来:

用单纯的想法来思考:initial cnt = 0 , set = {} ; cnt 用来记录当前的set中互质的对数 。

while (query --)

get (x) ;

travel set ---> if (find set(i) 互质 x)cnt ++ ;

set.insert (x) ;

end;

复杂度O(n^2);

来优化一下吧,如过我们知道1~5e5 里每个数的所有因数。并用一个cnt[ 50000 ]来表示当前集合中放的因数的出现次数:

比如说放了2 : 1 , 2, 3 : 1 , 3, 6 : 1 , 2 , 3 , 6 。

那么cnt[1] = 3 , cnt[2] = 2 , cnt [3] = 3 , cnt[6] = 1 ;

........然后自己yy吧。

感谢PauGra非常简单明了的code:

 #include<vector>
#include<stdio.h>
#include<string.h>
#include<algorithm>
typedef long long ll ;
const int M = 5e5 + ;
int n , q ;
int a[M] ;
int dp[M] , cnt[M] ;
bool vis[M] ;
std::vector <int> g[M] ; void table ()
{
dp[] = ;
for (int i = ; i < M ; i ++) {
if (dp[i]) g[i].push_back(i) ;
for (int j = i + i ; j < M ; j += i ) {
if (dp[i]) g[j].push_back(i) ;
dp[j] -= dp[i] ;
}
}
} int main ()
{
//freopen ("a.txt" , "r" , stdin ) ;
table () ;
printf ("27: %d\n" , dp[]) ;
scanf ("%d%d" , &n , &q) ;
for (int i = ; i <= n ; i ++) scanf ("%d" , &a[i]) ;
ll ans = ;
while (q --) {
int x ;
scanf ("%d" , &x) ;
if (vis[x]) {
for (int i : g[ a[x] ]) ans -= 1ll * dp[i] * (-- cnt [i]) ;
} else {
for (int i : g[ a[x] ]) {
ans += 1ll * dp[i] * (cnt[i] ++) ;
}
}
vis[x] ^= ;
printf ("%I64d\n" , ans) ;
}
return ;
}

cf#305 Mike and Foam(容斥)的更多相关文章

  1. Codeforces.547C.Mike and Foam(容斥/莫比乌斯反演)

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

  2. Codeforces 548E Mike ans Foam (与质数相关的容斥多半会用到莫比乌斯函数)

    题面 链接:CF548E Description Mike is a bartender at Rico's bar. At Rico's, they put beer glasses in a sp ...

  3. codeforces #305 C Mike and Foam

    首先我们注意到ai<=50w 因为2*3*5*7*11*13*17=510510 所以其最多含有6个质因子 我们将每个数的贡献分离, 添加就等于加上了跟这个数相关的互素对 删除就等于减去了跟这个 ...

  4. CF(439E - Devu and Birthday Celebration)莫比乌斯容斥

    题意:将n个糖果插入f-1个挡板分成f分(a1,a2,a3...af). 问有多少种分法能够使得gcd(a1,a2,a3...af)=1; 解法.莫比乌斯容斥,首先按1为单位分,这时候有C(n-1,f ...

  5. Codeforces 547C/548E - Mike and Foam 题解

    目录 Codeforces 547C/548E - Mike and Foam 题解 前置芝士 - 容斥原理 题意 想法(口胡) 做法 程序 感谢 Codeforces 547C/548E - Mik ...

  6. UVA11806Cheerleaders(容斥)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 题目意思:在m行n列的矩形网格中放k个相同的石子,问有多少中方法?每个格子最多放一 ...

  7. 【CF715E】Complete the Permutations(容斥,第一类斯特林数)

    [CF715E]Complete the Permutations(容斥,第一类斯特林数) 题面 CF 洛谷 给定两个排列\(p,q\),但是其中有些位置未知,用\(0\)表示. 现在让你补全两个排列 ...

  8. 【容斥原理,莫比乌斯反演】用容斥替代莫比乌斯反演第二种形式解决gcd统计问题

    名字虽然很长.但是其实很简单,对于这一类问题基本上就是看你能不能把统计的公式搞出来(这时候需要一个会推公式的队友) 来源于某次cf的一道题,盼望上紫的我让潘学姐帮我代打一道题,她看了看跟我说了题解,用 ...

  9. BZOJ.5407.girls/CF985G. Team Players(三元环计数+容斥)

    题面 传送门(bzoj) 传送门(CF) \(llx\)身边妹子成群,这天他需要从\(n\)个妹子中挑出\(3\)个出去浪,但是妹子之间会有冲突,表现为\(i,j\)之间连有一条边\((i,j)\), ...

随机推荐

  1. python deep copy and shallow copy

    Python中对于对象的赋值都是引用,而不是拷贝对象(Assignment statements in Python do not copy objects, they create bindings ...

  2. Python基本数据类型之dict

    一.创建字典: d = { "name": "morra", #字典是无序的 "age": 99, "gender": ...

  3. BZOJ1202 [HNOI2005]狡猾的商人&&BZOJ3436小K的农场

    差分约束第三题 传送门: 很明显的差分约束,d[y]-d[x-1]>=v d[y]-d[x-1]<=v 根据这个建图然后跑bellman-ford就可以了. //BZOJ 1202 //b ...

  4. Install R & RStudio for Ubuntu

    Install R r-project.org official source to install the latest R system. add R source   sudo vi /etc/ ...

  5. java编程思想-复用类总结

    今天继续读<java 编程思想>,读到了复用类一章,看到总结写的很好,现贴上来,给大家分享. 继承和组合都能从现有类型生成新类型.组合一般是将现有类型作为新类型底层实现的一部分来加以复用, ...

  6. 二维码(QRcode)容量的计算与版本

    4.版本信息:即二维码的规格,QR码符号共有40种规格的矩阵(一般为黑白色),从21x21(版本1),到177x177(版本40),每一版本符号比前一版本每边增加4个模块. 177 = 21+(40- ...

  7. fcc的中级算法题

    核心提示:这是网上开源编程学习项目FCC的javascript中级编程题(Intermediate Algorithm Scripting(50 hours)),一共20题.建议时间是50个小时,对于 ...

  8. cx_freeze 把 .py 打包成 .exe

    1.安装 python-3.4.3 默认安装路径 C:\Python34 2.安装 cx_Freeze-4.3.3.win32-py3.4 3.运行 Python Version 3.4 regist ...

  9. canvas入门(画圆)

    1.想在H5上画一个canvas,必须在页面上你需要的地方添加canvas标签, <canvas id="myCanvas"></canvas>   接着需 ...

  10. ConfuserEx

    今天给大家介绍一个开源.net混淆器——ConfuserEx http://yck1509.github.io/ConfuserEx/ 由于项目中要用到.net 混淆器,网上搜寻了很多款,比如Dotf ...