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. java异常的原理以及应用

    父类Throwable 两个分支: error:合理的应用程序不应该出现的严重问题,可以无需声明便抛出,比如内存溢出. Exception:程序还能够克服和恢复的问题. 其中又分为系统异常和普通异常. ...

  2. T61

    你参加了这次科学讨论会,有什么体会?What have you learned from the symposium?那墙有点斜.The wall is a little out of the per ...

  3. Thread,Service和AsyncTask

    Thread,Service和AsyncTask这三种东西,似乎都是用来执行后台耗时操作的: 印象里Service是「超过5s的耗时操作就应该放进去」,但是Service实际上仍然是主线程,所以,在S ...

  4. python打印字体颜色

        格式:\033[显示方式;前景色;背景色m 显示方式           意义-------------------------0                终端默认设置1         ...

  5. 「LOJ#10056」「一本通 2.3 练习 5」The XOR-longest Path (Trie

    #10056. 「一本通 2.3 练习 5」The XOR-longest Path 题目描述 原题来自:POJ 3764 给定一棵 nnn 个点的带权树,求树上最长的异或和路径. 输入格式 第一行一 ...

  6. VIJOS:P1082丛林探险

    描述 东非大裂谷中有一片神秘的丛林,是全世界探险家的乐园,著名黄皮肤探险家BB一直想去试试.正好我国科学家2005年4月将首次对东非大裂谷进行科考,BB决定随科考队去神秘丛林探险.在出发之前,他搜集了 ...

  7. BI 底座——数据仓库技术(Data Warehouse)

    在开始喷这个主题之前,让我们先看看数据仓库的官方定义: 数据仓库(Data Warehouse)是一个面向主题的(Subject Oriented).集成的(Integrate).相对稳定的(Non- ...

  8. python的logging模块详细使用demo

    import logging import os from logging import handlers from datetime import datetime class MyLog(): d ...

  9. Hibernate&nbsp;Annotation&nbsp;(…

    引自:http://www.cnblogs.com/hongten/archive/2011/07/20/2111773.html 进入:http://www.hibernate.org 说明文档: ...

  10. plsql&nbsp;分页

     select * from (select rownum rn,ps.* from (select * from user_t) ps ) where rn>=1 and rn<=10 ...