Codeforces 839D Winter is here - 暴力 - 容斥原理

Winter is here at the North and the White Walkers are close. John Snow has an army consisting of n soldiers. While the rest of the world is fighting for the Iron Throne, he is going to get ready for the attack of the White Walkers.

He has created a method to know how strong his army is. Let the i-th soldier’s strength be ai. For some k he calls i1, i2, ..., ik a clan if i1 < i2 < i3 < ... < ik and gcd(ai1, ai2, ..., aik) > 1 . He calls the strength of that clan k·gcd(ai1, ai2, ..., aik). Then he defines the strength of his army by the sum of strengths of all possible clans.

Your task is to find the strength of his army. As the number may be very large, you have to print it modulo 1000000007 (109 + 7).

Greatest common divisor (gcd) of a sequence of integers is the maximum possible integer so that each element of the sequence is divisible by it.

Input

The first line contains integer n (1 ≤ n ≤ 200000) — the size of the army.

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 1000000) — denoting the strengths of his soldiers.

Output

Print one integer — the strength of John Snow‘s army modulo 1000000007 (109 + 7).

Examples

input

33 3 1

output

12

input

42 3 4 6

output

39

Note

In the first sample the clans are {1}, {2}, {1, 2} so the answer will be 1·3 + 1·3 + 2·3 = 12



  题目大意 给定n,集合A,设表示把这个集合内的所有数求最大公约数的结果,求

  根据常用套路,套一个循环去枚举gcd的结果,然后再求系数,于是有

  现在设,于是有

  现在考虑求f(i)。可以想到容斥原理。

  先假设所有的集合的gcd是i的倍数都符合条件然后计算答案(给定数集A中所有是i的倍数的数组成的集合任选一个子集),然后再减去f(2i), f(3i),...

  现在要面临两个问题

  1. 第一次求值如何处理?
    首先把式子写出来,设这个集合的大小为n,那么有

    因为

    对两边同时进行求导得到

    再带入x = 1得到

  2. 为是i的倍数的数的个数,如何快速求出?

    根据定义式有

    显然超时。虽然这是暴力,但是不够优美。
    表示,集合A中恰好为i的数有多少个。

    然后就可以得到总时间复杂度为O(mlog2m)的暴力:

  最后求求和就完事了。

Code

 1 /**
 2  * Codeforces
 3  * Problem#839D
 4  * Accepted
 5  * Time: 171ms
 6  * Memory: 15400k
 7  */
 8 #include <bits/stdc++.h>
 9 using namespace std;
10
11 const int lim = 1e6 + 1;
12 const int moder = 1e9 + 7;
13
14 int n;
15 int *a;
16 int *pow2;
17 int cnt[lim], counter[lim];
18 int f[lim];
19 int res = 0;
20
21 inline void init() {
22     scanf("%d", &n);
23     a = new int[(n + 1)];
24     pow2 = new int[(n + 1)];
25     pow2[0] = 1;
26     for(int i = 1; i <= n; i++) {
27         scanf("%d", a + i);
28         counter[a[i]]++;
29         pow2[i] = (pow2[i - 1] << 1) % moder;
30     }
31 }
32
33 inline void solve() {
34     for(int i = 1; i < lim; i++)
35         for(int j = i; j < lim; j += i)
36             cnt[i] += counter[j];
37
38     for(int i = lim - 1; i > 1; i--) {
39         if(!cnt[i])    continue;
40         f[i] = (cnt[i] * 1LL * pow2[cnt[i] - 1]) % moder;
41         for(int j = i << 1; j < lim; j += i)
42             f[i] = (f[i] - f[j]) % moder;
43         if(f[i] < 0)    f[i] += moder;
44         res = (res + (f[i] * 1LL * i) % moder) % moder;
45     }
46
47     printf("%d\n", res);
48 }
49
50 int main() {
51     init();
52     solve();
53     return 0;
54 }
时间: 2024-08-11 08:57:18

Codeforces 839D Winter is here - 暴力 - 容斥原理的相关文章

Codeforces 839D Winter is here(容斥原理)

[题目链接] http://codeforces.com/contest/839/problem/D [题目大意] 给出一些数,求取出一些数,当他们的GCD大于0时,将数量乘GCD累加到答案上, 求累加和. [题解] 我们枚举GCD,统计为其倍数的数字数量,先假定其能组成的集合数为贡献, 但是我们发现在统计的过程中有多余统计的部分,比如4和8是2的倍数, 然而它们的GCD等于4,所以我们对于每个集合数的贡献要减去所有其倍数的集合数的贡献, 倒着容斥即可. [代码] #include <cstdi

Codeforces 443A Borya and Hanabi(暴力)

题目链接:Codeforces 443A Borya and Hanabi 题目大意:有若干个牌,每张牌有花色和数字两个值,现在问说至少询问多少次才能区分出所有的牌,每次询问可以确定一种花色牌的位置,或者是一种数字牌的位置. 解题思路:暴力枚举需要问的花色和数字,210,然后枚举两两判断是否可以被区分. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const

Codeforces 850A - Five Dimensional Points(暴力)

原题链接:http://codeforces.com/problemset/problem/850/A 题意:有n个五维空间内的点,如果其中三个点A,B,C,向量AB,AC的夹角不大于90°,则点A是"bad"的否则是"good".题目让我们输出good的点. 思路:从2,3维空间超过5,7个点时不存在"good"的点,可以简单推知五维空间内,超过11个点时不存在"good"的点,那么点数小于11时暴力,大于11时输出0. 其

Codeforces Gym 100203G Good elements 暴力乱搞

原题链接:http://codeforces.com/gym/100203/attachments/download/1702/statements.pdf 题解 考虑暴力的复杂度是O(n^3),所以我们需要记录所有的ai+aj,如果当前考虑到了ak,那么就去前面寻找ai,使得ak-ai是我们记录过的和.整个算法的复杂度O(n^2). 代码 #include<iostream> #include<cstring> #include<cstdio> #include<

Codeforces Gym 100637G G. #TheDress 暴力

G. #TheDress Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100637/problem/G Description After landing on planet i1c5l people noticed that blue and black clothes are quite popular among the locals. Each aboriginal has at least

Codeforces gym 100685 A. Ariel 暴力

A. ArielTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100685/problem/A Description King Triton really likes watching sport competitions on TV. But much more Triton likes watching live competitions. So Triton decides to set up

Codeforces 460E Roland and Rose(暴力)

题目链接:Codeforces 460E Roland and Rose 题目大意:在以原点为圆心,半径为R的局域内选择N个整数点,使得N个点中两两距离的平方和最大. 解题思路:R最大为30,那么其实距离圆心距离最大的整数点不过12个最多,直接暴力枚举. #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; struct

CodeForces 702B Powers of Two (暴力,优化)

题意:给定 n 个数,问你从有多少下标 i < j,并且 ai + aj 是2的倍数. 析:方法一: 从输入开始暴力,因为 i < j 和 i > j 是一样,所以可以从前面就开始查找,然后计数,用个map就搞定,不过时间有点长,接近两秒. 方法二: 先排序,然后暴力,暴力的原则是找前面的,也是用map查找,时间62ms. 代码如下: #include <cstdio> #include <string> #include <cstdlib> #inc

CodeForces 200C Football Championship(暴力枚举)

C. Football Championship time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Any resemblance to any real championship and sport is accidental. The Berland National team takes part in the local