zoukankan      html  css  js  c++  java
  • CF 839 D

    D. Winter is here
    time limit per test
    3 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    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

     

    Solution:

    首先有f(n)=Σi*C(i,n)(1<=i<=n)=i*2i-1.

    设ans[i]为gcd=i时的答案.

    这要怎么求呢,首先什么是比较好求的呢?如果我们问的不是gcd,而是能整除(有哪些组都能被i整除的数,再分别乘以它们的元素个数),那不是很妙?

    如果这样,我们不是只要求出有多少数能整除i,设其个数为n,那么答案就是f(n),不是吗?

    其实就算问题是gcd,我们依然可以这么算,只不过会多计入gcd=2*i的,gcd=3*i的......那减去不就好了?反正是调和级数一个log而已是吧!

    那么问题就结束了ans[i]=f[i]-Σans[j*i]

    Code:

     

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    #define ll long long
    const int MAXN=200000;
    const int MAXA=1000000;
    const int MOD=1e9+7;
    int n,a[MAXN+10];
    int cnt[MAXA+10],f[MAXA+10],pow2[MAXN+10],ans[MAXA+10];
    int AddMod(int a,int b){a+=b;return a>=MOD?a-MOD:a;}
    int MinusMod(int a,int b){a-=b;return a<0?a+MOD:a;}
    void init()
    {
    	pow2[0]=1;
    	for(int i=1;i<=n;++i)++cnt[a[i]],pow2[i]=AddMod(pow2[i-1],pow2[i-1]);
    	for(int i=1;i<=MAXA;++i)
    	{
    		for(int j=1;(ll)j*i<=MAXA;++j)
    			f[i]+=cnt[j*i];
    		if(f[i])f[i]=(ll)f[i]*pow2[f[i]-1]%MOD;
    	}
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i)scanf("%d",a+i);
    	init();
    	int res=0;
    	for(int i=MAXA;i>=2;i--)
    	{
    		ans[i]=f[i];
    		for(int j=2;(ll)j*i<=MAXA;++j)
    			ans[i]=MinusMod(ans[i],ans[j*i]);
    		res=AddMod(res,(ll)i*ans[i]%MOD);
    	}
    	printf("%d",res);
    	return 0;
    }
    

     

      

     

  • 相关阅读:
    [51nod1247]可能的路径(思维题)
    天梯赛L1020 帅到没朋友(map的使用)(模拟,数组非排序去重)
    洛谷 p1030 树的遍历
    天梯赛L1046 整除光棍(模拟)
    牛客,并查集,简单dp经商
    天梯赛L1043 阅览室 模拟题
    天梯赛L1049(模拟+vector的使用)
    天梯赛L1011,简单模拟
    codeforces 1201 c
    天梯赛L2003月饼(简单排序题)
  • 原文地址:https://www.cnblogs.com/DOlaBMOon/p/7356564.html
Copyright © 2011-2022 走看看