function HDU - 5608

function

 HDU - 5608 

 题意:典型的莫比乌斯反演就不用说了。。。

公式不会推,看的题解=_= 链接

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 const ll mod = 1e9+7;
 5 const ll maxn = 1e6+10;
 6 
 7 ll pri[maxn];
 8 ll mu[maxn];
 9 map<ll, ll> hs;
10 
11 void init(){
12     ll cnt = 0;
13     memset(pri, 0, sizeof(pri));
14     mu[1] = 1;
15     for(ll i = 2; i < maxn; i++){
16         if(!pri[i]){
17             pri[cnt++] = i;
18             mu[i] = -1;
19         }
20         for(ll j = 0; j < cnt; j++) {
21             ll t = i * pri[j];
22             if(t >= maxn) break;
23             pri[t] = 1;
24             if(i % pri[j] == 0) {
25                 mu[t] = 0;
26                 break;
27             } else {
28                 mu[t] = -mu[i];
29             }
30         }
31         mu[i] =(mu[i]+mu[i-1])%mod;
32     }
33 }
34 
35 ll sum(ll x){
36     ll mod1 = 6LL*mod;
37     ll res = x*(x+1)%mod1*(2*x+1)%mod1/6;
38     ll mod2 = 2LL*mod;
39     ll temp = 3*x*(x+1)%mod2/2;
40     res = (res - temp + 2LL*x + mod) % mod;
41     return res;
42 }
43 
44 ll cal(ll n){
45     if(n < maxn) return mu[n];
46     if(hs[n]) return hs[n];
47     ll L = 2, R = 2;
48     ll ans = 1;
49     while(L <= n){
50         ans = (ans - (cal(n/R)*(R-L+1)+mod)%mod + mod) %mod;
51         if(R == n) break;
52         L = R+1;
53         R = n/(n/L);
54     }
55     return hs[n] = ans;
56 }
57 
58 ll solve(ll n){
59     ll res = 0;
60     ll L = 1, R = 1;
61     while(L <= n){
62         ll ans = cal(n/R) * ((sum(R)- sum(L-1) + mod)%mod) %mod;
63         res = ((ans+res)%mod + mod) %mod;
64         if(R == n) break;
65         L = R+1;
66         R = n/(n/L);
67     }
68     res = (res+mod)%mod;
69     return res;
70 }
71 
72 int main(){
73     init();
74     int t;
75     scanf("%d", &t);
76     while(t--){
77         ll n;
78         scanf("%lld", &n);
79         ll res = solve(n);
80         printf("%lld\n", res);
81     }
82     return 0;
83 }
View Code

 

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 #define ll long long
  4 const ll mod = 1e9+7;
  5 const ll maxn = 1e6+10;
  6 
  7 ll pri[maxn];
  8 ll mu[maxn];
  9 
 10 const int H_SZ = 13131;
 11 
 12 struct HS{
 13     ll val[H_SZ], res[H_SZ];
 14     int head[maxn], nex[maxn];
 15     int cnt;
 16     void init(){
 17         memset(head, -1, sizeof(head));
 18         cnt = 0;
 19     }
 20 
 21     void add(ll x, ll y){
 22         int u = x%H_SZ;
 23         val[cnt] = x;
 24         res[cnt] = y;
 25         nex[cnt] = head[u];
 26         head[u] = cnt++;
 27     }
 28     ll query(ll x){
 29         int u = x%H_SZ;
 30         for(int i = head[u]; ~i; i = nex[i]){
 31             if(val[i] == x) return res[i];
 32         }
 33         return H_SZ;
 34     }
 35 }hs;
 36 
 37 void init(){
 38     ll cnt = 0;
 39     memset(pri, 0, sizeof(pri));
 40     mu[1] = 1;
 41     for(ll i = 2; i < maxn; i++){
 42         if(!pri[i]){
 43             pri[cnt++] = i;
 44             mu[i] = -1;
 45         }
 46         for(ll j = 0; j < cnt; j++) {
 47             ll t = i * pri[j];
 48             if(t >= maxn) break;
 49             pri[t] = 1;
 50             if(i % pri[j] == 0) {
 51                 mu[t] = 0;
 52                 break;
 53             } else {
 54                 mu[t] = -mu[i];
 55             }
 56         }
 57         mu[i] =(mu[i]+mu[i-1])%mod;
 58     }
 59 }
 60 
 61 inline ll sum(ll x){
 62     ll mod1 = 6LL*mod;
 63     ll res = x*(x+1)%mod1*(2*x+1)%mod1/6;
 64     ll mod2 = 2LL*mod;
 65     ll temp = 3*x*(x+1)%mod2/2;
 66     res = (res - temp + 2LL*x + mod) % mod;
 67     return res;
 68 }
 69 
 70 ll cal(ll n){
 71     if(n < maxn) return mu[n];
 72     if(hs.query(n) != H_SZ) return hs.query(n);
 73     ll L = 2, R = 2;
 74     ll ans = 1;
 75     while(L <= n){
 76         ans = (ans - (cal(n/R)*(R-L+1)+mod)%mod + mod) %mod;
 77         if(R == n) break;
 78         L = R+1;
 79         R = n/(n/L);
 80     }
 81     hs.add(n, ans);
 82     return ans;
 83 }
 84 
 85 ll solve(ll n){
 86     ll res = 0;
 87     ll L = 1, R = 1;
 88     while(L <= n){
 89         ll ans = sum(n/R) * ((cal(R)- cal(L-1) + mod)%mod) %mod;
 90         res = ((ans+res)%mod + mod) %mod;
 91         if(R == n) break;
 92         L = R+1;
 93         R = n/(n/L);
 94     }
 95     res = (res+mod)%mod;
 96     return res;
 97 }
 98 
 99 int main(){
100     init();
101     hs.init();
102     int t;
103     scanf("%d", &t);
104     while(t--){
105         ll n;
106         scanf("%lld", &n);
107         ll res = solve(n);
108         printf("%lld\n", res);
109     }
110     return 0;
111 }
hash——table

 

转载于:https://www.cnblogs.com/yijiull/p/7629265.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值