• 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
    3
    3 3 1
    output
    12
    input
    4
    2 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
    ", res);
    48 }
    49 
    50 int main() {
    51     init();
    52     solve();
    53     return 0;
    54 }

    更新日志

    • 2017-11-30 更新两处指数错误
  • 相关阅读:
    分区硬盘Lvm 折腾小记
    添加源ubuntu_x64 安装 Adobe Reader
    停止标记NYOJ 一个简单的数学题 南工330停止标记
    读控制台HDU 1788 Chinese remainder theorem again 数论读控制台
    对象方法PHP中魔术方法的用法对象方法
    指针修饰C语言const修饰符探秘指针修饰
    输入整数角谷步数 你听说过角谷猜想吗? 任意的正整数,比如 5, 我们从它开始,如下规则计算: 如果是偶数,则除以2,如果是奇数,则乘以3再加1. 如此循环,最终必会得到“1” !输入整数
    根节点左边POJ 1456 Supermarket根节点左边
    代码功能【OpenGL】初识OpenGL4.0代码功能
    终点节点NYOJ115 城市平乱终点节点
  • 原文地址:https://www.cnblogs.com/yyf0309/p/7365402.html
Copyright © 2020-2023  润新知