http://codeforces.com/problemset/problem/548/E

这题是询问id,如果这个id不在,就插入这个id,然后求a[id1] ,  a[id2]互质的对数。

询问有多少个互质这个套路出了很多次,这次是在线

首先维护当前的ans,可以知道每一步的ans,都是由于上一步的ans递推过来的。就是小答案可以由大答案推过来。

就是现在数组是a[] = 1, 2, 3,维护一个ans表示有多少对gcd等于1,然后添加一个4,只需要询问4在a[] = {1, 2, 3}中有多少个和它互质,即可。

(有时候也需要总体分析。-  - ,与这题无关)

分析:

怎么说呢,很久之后我看到这题,发现压根就没写详解,虽然自己记得具体解法,但是却没理论论证。想了一晚,现在回忆起来了。

难点就是在于给定一个集合,然后给你一个数,问这个集合里面有多少个数与它互质。

比如现在集合是:4、6、8、9、11

询问数字:12

与它gcd = 1, 相当于  size - (gcd != 1)对立面。

设gcd[i]表示与查询数gcd = i的总数

然后就是相当于  size -  (gcd[2] + gcd[3] + gcd[4] + gcd[5] + ..... + gcd[12])

然后这样很明显会是减多了。比如gcd[6],会在gcd[2]的时候减一次,gcd[3]减一次,gcd[6]减一次。这样相当于减了3次。

所以每个gcd[i]前面应该还有一个系数控制它减多少。这个系数嘛,就是mobius[i],这个就不说啦,当我们都懂了。就是gcd的容斥。

比如mobius[4] = 0,因为gcd[4]会在gcd[2]和gcd[4]的时候各减去一次,同时需要保留一次,就保留了gcd = 2的,(mobius[2] = -1)

而mobius[6] = 1,因为gcd[6],会在gcd[2]的时候减一次,gcd[3]减一次,gcd[6]减一次。这样相当于减了3次。那么如果在gcd[6]的时候加回一次,就相当于减去了一次而已。满足条件。

回到题目,如果每次都和上面这样做,复杂度O(val),因为要枚举2----val之间的数字。

但是有很多东西是不必要的枚举,比如枚举gcd[7],根本没有数字可能与12  gcd = 7

所以只需要枚举12的因子即可,12 = 2 * 2 * 3,因子有2、3、4、6、12,每个因子是加是减,也是由Mobius[i]决定。

但是这样枚举也很多的哦,

首先知道没必要枚举4,因为mobius[4] = 0,也没必要枚举12,同理mobius[12] = 0

那么把12写成     12 = 2 * 3,就是每个质因子出现的次数只保留一次,然后有约数是2、3、6,去容斥即可,奇加偶减

做到了每个数字的mobius[i]都 != 0,枚举都是有必要的。

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = + ;
int prime[maxn][], a[maxn];
void init() {
for (int i = ; i <= maxn - ; ++i) {
if (prime[i][]) continue;
for (int j = i; j <= maxn - ; j += i) {
prime[j][++prime[j][]] = i;
}
}
// prime[1][0] = 1;
// prime[1][1] = 1;
}
bool in[maxn];
int num[maxn];
void maintain(int val, int op) {
int en = ( << prime[val][]) - ;
for (int i = ; i <= en; ++i) {
int res = ;
for (int j = ; j <= prime[val][]; ++j) {
if (i & ( << (j - ))) res *= prime[val][j];
}
num[res] += op;
}
}
LL ans;
LL getAns(int val) {
LL ans = ;
int en = ( << prime[val][]) - ;
for (int i = ; i <= en; ++i) {
int res = ;
int sel = ;
for (int j = ; j <= prime[val][]; ++j) {
if (i & ( << (j - ))) {
++sel;
res *= prime[val][j];
}
}
if (sel & ) ans += num[res];
else ans -= num[res];
}
return ans;
}
void work() {
int n, q, tot = ;
scanf("%d%d", &n, &q);
for (int i = ; i <= n; ++i) scanf("%d", a + i);
for (int i = ; i <= q; ++i) {
int id;
scanf("%d", &id);
if (in[id]) {
maintain(a[id], -);
in[id] = false;
ans -= getAns(a[id]);
tot--;
} else {
ans += getAns(a[id]);
maintain(a[id], );
in[id] = true;
tot++;
}
printf("%I64d\n", 1LL * tot * (tot - ) / - ans);
}
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
init();
// int val = 4;
// for (int i = 1; i <= prime[val][0]; ++i) {
// printf("%d ", prime[val][i]);
// }
// printf("\n");
work();
return ;
}

http://www.cnblogs.com/liuweimingcprogram/p/6919379.html

E. Mike and Foam 容斥原理的更多相关文章

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

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

  2. E. Mike and Foam(容斥原理)

    E. Mike and Foam Mike is a bartender at Rico's bar. At Rico's, they put beer glasses in a special sh ...

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

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

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

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

  5. Codeforces548E:Mike and Foam

    Mike is a bartender at Rico's bar. At Rico's, they put beer glasses in a special shelf. There are n  ...

  6. 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 ...

  7. Mike and Foam(位运算)

    English reading: bartender == barmaid:酒吧女招待 milliliter:毫升:千分之一毫升 foam:泡沫 a glass of beer with a good ...

  8. codeforces #305 C Mike and Foam

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

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

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

随机推荐

  1. LinkedList_1.打印两个有序链表的公共部分

    思路: 实例化出两个链表($link_a, $link_b),比较连个链表当前元素的大小,谁小谁执行next()方法继续比较,当出现相当的时候把相等的值塞入数组$common里,当两个链表有一个元素比 ...

  2. aoj 0118 Property Distribution

    タナカ氏が HW アールの果樹園を残して亡くなりました.果樹園は東西南北方向に H × W の区画に分けられ.区画ごとにリンゴ.カキ.ミカンが植えられています.タナカ氏はこんな遺言を残していました. ...

  3. 洛谷 P2962 [USACO09NOV]灯Lights

    题目描述 Bessie and the cows were playing games in the barn, but the power was reset and the lights were ...

  4. POJ1006Biorhythms——中国剩余定理

    题目:http://poj.org/problem?id=1006 用扩展欧几里得算法求逆元,使用中国剩余定理: 本题较简单,可以手算直接写出,不过我仍使用了模板. 代码如下: #include< ...

  5. DTP模型之一:(XA协议之三)MySQL数据库分布式事务XA优缺点与改进方案

    1 MySQL 外部XA分析 1.1 作用分析 MySQL数据库外部XA可以用在分布式数据库代理层,实现对MySQL数据库的分布式事务支持,例如开源的代理工具:ameoba[4],网易的DDB,淘宝的 ...

  6. Django admin有用的自定义功能

    引用园友 无名小妖 的博客 https://www.cnblogs.com/wumingxiaoyao/p/6928297.html 写的很好,但是博客园不能转载,不过我已经点赞了~

  7. scaleform中ActionScript和UnrealScript的交互

    转自:http://www.cnblogs.com/NEOCSL/p/4174134.html scaleform是制作UI的好工具: 1.他可以解放程序员用代码控制的UI效果,例如平移,旋转和缩放都 ...

  8. 三 lambda表达式有什么用

    (转载: https://mp.weixin.qq.com/s/-PHOc6p-qKJBktle28AUgA) 一: 直接把代码块赋值给变量 我们知道,对于一个Java变量,我们可以赋给其一个“值”. ...

  9. url&nbsp;传递参数(特殊字符)解决方法

    url 传递参数(特殊字符)解决方法 首先设置 apache 配置文件, server.xml 在 port=8080 那一行中加上 URIEcoding=GBK 有些符号在URL中是不能直接传递的, ...

  10. 使用Spring的jdbcTemplate进一步简…

    先看applicationContext.xml配置文件:  版权声明:本文为博主原创文章,未经博主允许不得转载.