E. Mike and Foam 容斥原理
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 容斥原理的更多相关文章
- hdu4135-Co-prime & Codeforces 547C Mike and Foam (容斥原理)
hdu4135 求[L,R]范围内与N互质的数的个数. 分别求[1,L]和[1,R]和n互质的个数,求差. 利用容斥原理求解. 二进制枚举每一种质数的组合,奇加偶减. #include <bit ...
- 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 ...
- Codeforces 547C/548E - Mike and Foam 题解
目录 Codeforces 547C/548E - Mike and Foam 题解 前置芝士 - 容斥原理 题意 想法(口胡) 做法 程序 感谢 Codeforces 547C/548E - Mik ...
- cf#305 Mike and Foam(容斥)
C. Mike and Foam time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- 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 ...
- 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 ...
- Mike and Foam(位运算)
English reading: bartender == barmaid:酒吧女招待 milliliter:毫升:千分之一毫升 foam:泡沫 a glass of beer with a good ...
- codeforces #305 C Mike and Foam
首先我们注意到ai<=50w 因为2*3*5*7*11*13*17=510510 所以其最多含有6个质因子 我们将每个数的贡献分离, 添加就等于加上了跟这个数相关的互素对 删除就等于减去了跟这个 ...
- codeforces 547c// Mike and Foam// Codeforces Round #305(Div. 1)
题意:给出数组arr和一个空数组dst.从arr中取出一个元素到dst为一次操作.问每次操作后dst数组中gcd等于1的组合数.由于数据都小于10^6,先将10^6以下的数分解质因数.具体来说从2开始 ...
随机推荐
- Linux_学习_01_ 压缩文件夹
二.参考资料 1.Linux下压缩某个文件夹命令
- windows与Linux操作系统的差别
用户需要记住:Linux和Windows在设计上就存在哲学性的区别.Windows操作系统 倾向于将更多的功能集成到操作系统内部,并将程序与内核相结合:而Linux不同 于Windows,它的内核空间 ...
- POJ3468 A Simple Problem with Integers(数状数组||区间修改的RMQ问题)
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of op ...
- 四维偏序 CDQ套CDQ
对CDQ深一步的理解 昨天做了一道CDQ,看了一堆CDQ可做的题,今天又做了一道四维偏序 感觉对CDQ的理解又深了一点,故来写一写现在自己对于CDQ的理解 CDQ其实就是实现了这样的一个问题的转化: ...
- [SHOI 2017] 分手是祝愿
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=4872 [算法] 首先发现 , 对于一个开关 , 按下2次和没按是等价的 , 因此每个 ...
- 解决CentOS 7安装zabbix 3.0 无法启动zabbix-server的问题[segfault at 18 ip 00007f78842b4bd0 sp 00007fff1995a818 error 4 in libpthread-2.17.so[7f78842ab000+16000]]
解决CentOS 7安装zabbix 3.0 无法启动zabbix-server的问题 [root@localhost sbin]# service zabbix-server start Redir ...
- websocket之二:WebSocket编程入门
一.WebSocket客户端 websocket允许通过JavaScript建立与远程服务器的连接,从而实现客户端与服务器间双向的通信.在websocket中有两个方法: 1.send() 向远程服务 ...
- VS2005打开VS2008项目的2种方法
vs2008支持.net3.5,而vs2005支持.net2.0,所以使用vs2005打开vs2008的项目,要确定你的项目是.net2.0的. 下面介绍2种方法: 方法1:用记事本打开.sln文件, ...
- 细说ASP.NET Forms身份认证 别人写的不过很透彻就转来了以后用时再看
阅读目录 开始 ASP.NET身份认证基础 ASP.NET身份认证过程 如何实现登录与注销 保护受限制的页面 登录页不能正常显示的问题 认识Forms身份认证 理解Forms身份认证 实现自定义的身份 ...
- web性能并发测试工具(转)
导读:随着Web 2.0技术的迅速发展,许多公司都开发了一些基于Web的网站服务,通常在设计开发Web应用系统的时候很难模拟出大量用户同时访问系统的实际情况,因此,当Web网站遇到访问高峰时,容易发生 ...