E - Sum of gcd of Tuples (Hard)

深夜水题一发

Problem Statement

Consider sequences {A1,...,AN}{A1,...,AN} of length NN consisting of integers between 11 and KK (inclusive).

There are KNKN such sequences. Find the sum of gcd(A1,...,AN)gcd(A1,...,AN) over all of them.

Since this sum can be enormous, print the value modulo (109+7)(109+7).

Here gcd(A1,...,AN)gcd(A1,...,AN) denotes the greatest common divisor of A1,...,ANA1,...,AN.

Constraints

  • 2≤N≤10^5
  • 1≤K≤10^5
  • All values in input are integers.

Input

Input is given from Standard Input in the following format:

N K

Output

Print the sum of gcd(A1,...,AN)gcd(A1,...,AN) over all KNKN sequences, modulo (109+7)(109+7).


Sample Input 1 Copy

Copy

3 2

Sample Output 1 Copy

Copy

9

题意:给你一个长度为n的序列,每一个数位的值限定于1-k之间,求每个可能的序列,其最大公因子之和。

思路:题意可以理解为求当序列最大公因子为 i (1<=i<=k) 时,可能序列的数量,这里设为 x ,那么将所有可能的x * i 加起来之后就得解。对于 i 来说,有 k / i 个可能的数字可以去添入当前数位,所以 x 暂定为 (k / i) ^ n,但是如果当前序列所有位都是不等于 i 的倍数时,最小公因子可能就会出现变化,比如 k = 8 ,i = 2时,可以尝试的倍数有 2 4 6 8其中对于4,8来说,最小公因子就为4。为了避免这种情况也被算进当前对于 i 的可行序列数量中,我们还需要减去对于 i 的倍数来说的可行序列数量(因为能够对当前序列有影响的是其他倍数之一自成序列的最大公因子)

#include<bits/stdc++.h>
#define OK cout << endl
#define f(a,j,k) for(int i = a ; i < j ; i += k)
#define f1(a,j,k) for(int i = a ; i > j ; i -= k)
using namespace std;
typedef long long ll;
typedef vector<long long> vl;
typedef vector<int> vi;
typedef pair<int,int> pri;
typedef pair<long long,long long> prl;
const ll M = 1e9 + 7;
ll Pow(ll i,ll n){
    ll ans = 1;
    while(n){
        if(n & 1) ans *= i,ans %= M;
        i *= i;
        i %= M;
        n >>= 1;
    }
  return ans;
}
void solve(){
   ll n , k;
   cin >> n >> k;
   ll ans = 0;
   ll a[k+5];
   ll res[k+5];
   f(1,k+1,1) a[i] = Pow(k/i,n) % M;
   f1(k,0,1){
      res[i] = a[i];
      for(ll j=i<<1;j <= k;j+=i)
      ((res[i]-=res[j])+=M)%=M;
   }
   f(1,k+1,1){
       (ans += res[i] * i) %= M;
   }
   cout << ans << endl;
}
int main() {
	  std::ios::sync_with_stdio(false);
	  int t;
		solve();

	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值