HDU 5382 GCD?LCM? (组合数学+筛法)*

GCD?LCM!

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 371    Accepted Submission(s): 233


 

Problem Description

First we define:
(1) lcm(a,b) , the least common multiple of two integers a and b , is the smallest positive integer that is divisible by both a and b . for example, lcm(2,3)=6 and lcm(4,6)=12 .
(2) gcd(a,b) , the greatest common divisor of two integers a and b , is the largest positive integer that divides both a and b without a remainder, gcd(2,3)=1 and gcd(4,6)=2 .
(3) [exp] , exp is a logical expression, if the result of exp is true , then [exp]=1 , else [exp]=0 . for example, [1+2≥3]=1 and [1+2≥4]=0 .

Now Stilwell wants to calculate such a problem:

F(n)=∑i=1n∑j=1n [ lcm(i,j)+gcd(i,j)≥n ]S(n)=∑i=1nF(i)


Find S(n) mod 258280327 .

 

 

Input

The first line of the input contains a single number T , the number of test cases.
Next T lines, each line contains a positive integer n .
T≤105 , n≤106 .

 

 

Output

T lines, find S(n) mod 258280327 .

 

 

Sample Input

 

8 1 2 3 4 10 100 233 11037

 

 

Sample Output

 

1 5 13 26 289 296582 3928449 213582482

 

 

Author

SXYZ

 

 

Source

2015 Multi-University Training Contest 8

 

 

Recommend

wange2014

 

 

#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;

#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)

#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define ll long long
/*
题目大意:求公式,及其前缀和。

一遇到求和公式里有gcd的,
一般都是在外面套一层sigma d (gcd=d)这样,
然后把gcd提取出来,把i和j压缩(在函数里就是换元)。
这时候要求i和j互质了。

先看等于号的情况(公式不会打,
具体可以参考大佬博客https://blog.csdn.net/consciousman/article/details/77888386)
下面就要考验对一个公式的理解能力了,
d(n^2)=sigma 2^(w(g)),
本来正常的积性函数拆解是
d(p1^2a1 * p2^2a2 * p3^2a3*...)
=(2*a1+1)*(2*a2+1)*...
根据组合的知识上下两个式子相等,
而题目中的这个式子转换本质也差不多,

还是组合的思想,
假如i选0个质数,组合数C(m,0)
假如i选1一个质数,组合数C(m,1),
假如i选2个质数,组合数:C(m,2),
.
.
.
这样排列下去,求和得到2^(m)。
即2^(W(n/g-1))。
分析时间复杂度,W函数可以线性筛处理,
F函数可以nlogn处理,其余的都是线性处理,符合要求。

单个的等于号情况求出来后,
下面就是一个线性递推的推导,注意加上去的2*i-1
是从式子里剖出来的,证明不难。
*/

const int  maxn =1e6+5;
const int mod=258280327;
ll powmod(ll x,ll y){ll t;for(t=1;y;y>>=1,x=x*x%mod)if(y&1) t=t*x%mod;return t;}
///线性筛质数和G函数(不同质因子个数)
int prim[maxn],cnt=0;
int G[maxn],vis[maxn];
void sieve()
{
    G[1]=0;
    memset(vis,0,sizeof(vis));
    for(int i=2;i<maxn;i++)
    {
        if(vis[i]==0)
        {
            prim[cnt++]=i;
            G[i]=1;
        }
        for(int j=0;j<cnt;j++)
        {
            int k=prim[j]*i;
            if(k>=maxn) break;
            vis[k]=1;
            if(i%prim[j]) G[k]=G[i]+1;
            else
            {
                G[k]=G[i];
                break;
            }
        }
    }
}

ll W[maxn];///贡献函数
 ll F[maxn];///答案函数
 int n;

int main()
{
    sieve();
    memset(W,0,sizeof(W));

    for(int i=1;i<maxn;i++)
        for(int j=i<<1,k=2;j<maxn;j+=i,k++)
            W[j]=(W[j]+powmod(2LL,G[k-1]))%mod;///可以常数优化下

    for(int i=1;i<maxn;i++) F[i]=(F[i-1]+2*i%mod-1-W[i-1]+mod)%mod;
    for(int i=1;i<maxn;i++) (F[i]+=F[i-1])%=mod;

    int t;scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        printf("%lld\n",F[n]);
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值