codeforces 548 E. Mike and Foam (莫比乌斯反演)
2015-12-09 21:28
639 查看
E. 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 1to 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 aand 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
output
思路:
问题转化一下就是给出n个数,对于某个数,和他互质的数有多少个,可以用莫比乌斯反演来解决这个问题。
对于一个数x,
f(d)表示和x的最大公约数为d的数有多少个
那么F(d)就表示和x的最大公约数为d的倍数的数有多少个
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 1to 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 aand 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
思路:
问题转化一下就是给出n个数,对于某个数,和他互质的数有多少个,可以用莫比乌斯反演来解决这个问题。
对于一个数x,
f(d)表示和x的最大公约数为d的数有多少个
那么F(d)就表示和x的最大公约数为d的倍数的数有多少个
/*====================================================== # Author: whai # Last modified: 2015-12-09 19:49 # Filename: e.cpp ======================================================*/ #include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include <cstring> #include <string> #include <cmath> #include <set> #include <map> #include <queue> #include <stack> using namespace std; #define LL __int64 #define PB push_back #define P pair<int, int> #define X first #define Y second const int N = 5 * 1e5 + 5; int a ; bool used ; int cnt ; LL ans = 0; int mu ; void getMu() { for(int i = 1; i < N; ++i) { int tar = i == 1 ? 1 : 0; int delta = tar - mu[i]; mu[i] = delta; for(int j = 2 * i; j < N; j += i) mu[j] += delta; } } void add(int x) { for(int i = 1; i * i <= x; ++i) { if(x % i == 0) { ans += mu[i] * cnt[i]; int tmp = x / i; if(i != tmp) ans += mu[tmp] * cnt[tmp]; } } for(int i = 1; i * i <= x; ++i) { if(x % i == 0) { ++cnt[i]; int tmp = x / i; if(i != tmp) ++cnt[tmp]; } } } void del(int x) { for(int i = 1; i * i <= x; ++i) { if(x % i == 0) { --cnt[i]; int tmp = x / i; if(i != tmp) --cnt[tmp]; } } for(int i = 1; i * i <= x; ++i) { if(x % i == 0) { ans -= mu[i] * cnt[i]; int tmp = x / i; if(i != tmp) ans -= mu[tmp] * cnt[tmp]; } } } int main() { getMu(); int n, q; scanf("%d%d", &n, &q); for(int i = 1; i <= n; ++i) { scanf("%d", &a[i]); } for(int i = 0; i < q; ++i) { int x; scanf("%d", &x); if(used[x] == 0) { add(a[x]); used[x] = 1; } else { del(a[x]); used[x] = 0; } printf("%I64d\n", ans); } return 0; }
相关文章推荐
- 学习笔记:第6章 程序语言基础知识
- Android布局之ListView
- JVM学习笔记(1)--java内存区域与内存溢出异常
- Centos7添加静态路由
- @protocol的一个小细节
- 使用java实现CNN的实战
- C#如何自定义DataGridViewColumn来显示TreeView
- nginx设置目录浏览及中文乱码问题解决
- 微信扫码支付报错:curl出错,错误码:60
- UNIX环境编程------原始套接字---原始套接字编程实例: 接收的链路层数据包,并对其进行简单分析
- 堆排序(HeapSort)
- 北京某高校可用的电话号码有以下几类:校内电话号码由4位数字,第1位数字不是0;校外电话又分为本市电话和外地电话两类,拔校外电话需先拔0,若是本市电话则再接着拔8位数字(第一位不是0),若是外地电话则拔3位区码再拔8位电话号码(第一位不是0)。
- 第三个Sprint冲刺第三天
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(三·完结)
- java 类修饰属性public
- 图之Kruskal算法实现-----最小生成树
- 多图片平均法降噪
- CentOS---网络配置详解
- 如何在Eclipse引入JUnit测试
- 目前住院病人主要由护士护理,这样做不仅需要大量的护士,而且由于不能随时观察危重病人的病情变化,还可能会延误抢救时机。某医院打算开发一个以计算机为中心的患者监护系统,试写出问题定义,并且分析开发这个系统的可行性。