[BZOJ4407]于神之怒加强版

Description

给下N,M,K.求

Input

输入有多组数据,输入数据的第一行两个正整数T,K,代表有T组数据,K的意义如上所示,下面第二行到第T+1行,每行为两个正整数N,M,其意义如上式所示。

Output

如题

Sample Input

1 2
3 3

Sample Output

20

HINT

1<=N,M,K<=5000000,1<=T<=2000

题解:JudgeOnline/upload/201603/4407.rar

Source

不会写公式QAQ

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define ll long long
 5 #define mod 1000000007
 6 #define M 5000010
 7 using namespace std;
 8 int n,m,T,K,tot;
 9 int P[M],s[M],sum[M];
10 bool vis[M];
11 int power(int a,int b)
12 {
13     int ans=1;
14     while(b)
15     {
16         if(b&1) ans=(ll)ans*a%mod;
17         a=(ll)a*a%mod; b>>=1;
18     }
19     return ans;
20 }
21 void pre()
22 {
23     sum[1]=1;
24     for(int i=2;i<=5000000;i++)
25     {
26         if(!vis[i]) {P[++tot]=i;s[tot]=power(i,K);sum[i]=s[tot]-1;}
27         for(int j=1;j<=tot&&P[j]*i<=5000000;j++)
28         {
29             vis[P[j]*i]=true;
30             if(i%P[j]==0) {sum[i*P[j]]=(ll)sum[i]*s[j]%mod;break;}
31             else sum[i*P[j]]=(ll)sum[i]*sum[P[j]]%mod;
32         }
33     }
34     for(int i=1;i<=5000000;i++) sum[i]=(sum[i]+sum[i-1])%mod;
35 }
36 int main()
37 {
38     scanf("%d%d",&T,&K);
39     pre();
40     while(T--)
41     {
42         ll ans=0;
43         scanf("%d%d",&n,&m);
44         if(n>m) swap(n,m);
45         for(int l=1,r;l<=n;l=r+1)
46         {
47             r=min(n/(n/l),m/(m/l));
48             ans+=(ll)(n/l)*(m/l)%mod*(sum[r]-sum[l-1])%mod;
49             ans%=mod;
50         }
51         printf("%lld\n",(ans+mod)%mod);
52     }
53     return 0;
54 }

猜你喜欢

转载自www.cnblogs.com/Slrslr/p/9576829.html
今日推荐