2018 Multi-University Training Contest 7 6390 GuGuFishtion【莫比乌斯反演】

http://acm.hdu.edu.cn/showproblem.php?pid=6390

昨天一下午,今天一上午,我已经快被这个题恶心死了。
TLE,TLE永远都是TLE。不得不说,我觉得卡我卡的没什么道理,非常的不爽!

卡内循环枚举变量类型我是真的不懂,发现知识盲区+1.

可是就算是再不爽也要含泪挖坑。

题意求:

(a=1mb=1nϕ(ab)ϕ(a)ϕ(b))mod(p) ( ∑ a = 1 m ∑ b = 1 n ϕ ( a b ) ϕ ( a ) ϕ ( b ) ) m o d ( p )

打表规律发现:

ϕ(ab)ϕ(a)ϕ(b)=gcd(a,b)ϕ(gcd(a,b)) ϕ ( a b ) ϕ ( a ) ϕ ( b ) = g c d ( a , b ) ϕ ( g c d ( a , b ) )

所以就可以通过莫比乌斯反演来计算

a=1nb=1m[k=gcd(a,b)] ∑ a = 1 n ∑ b = 1 m [ k = g c d ( a , b ) ]

最后通过枚举 k k 并乘上k和[ ϕ(k) ϕ ( k ) 的逆元]即可

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;
ll phi[maxn];
ll mu[maxn];
ll inv[maxn];
ll a[maxn];
ll cnt;ll p;ll T;int n,m;
void get_inv(ll n){
    inv[1]=1;
    for(ll i=2;i<=n;i++){
        inv[i]=(ll)(p-p/i)*inv[p%i]%p;
    }
    for(ll i=1;i<=n;i++){
        a[i]=(ll)i*inv[phi[i]]%p;
    }
}
void get_phi(){
    for(ll i=1;i<maxn;i++){
        phi[i]=i;
    }
    for(ll i=2;i<maxn;i++){
        if(phi[i]==i){
            for(ll j=i;j<maxn;j+=i)
                phi[j]-=phi[j]/i;
        }
    }
}
void get_mu() {
   mu[1] = 1;
   for(int i=1;i<maxn;i++){
    for(int j=2*i;j<maxn;j+=i){
        mu[j]-=mu[i];
    }
   }

}
int main()
{
    get_phi();
    get_mu();
    scanf("%lld", &T);
    while (T--) {
        scanf("%d%d%lld", &n, &m, &p);
        if (n > m) swap(n, m);
        ll res=min(n,m);
        get_inv(res);
        ll ans=0;
        ll tmp=0;
        for(ll d=1;d<=res;d++){
            tmp=0;
            //for (ll l = 1, r; l <= res; l = r + 1) {
              //  r = min(n / (n / l), m / (m / l));
               // tmp += 1ll*(n / (l*d))*(m / (l* d))*(sum[r] - sum[l - 1])%p;
           // }
            int x=n/d,y=m/d;
            ll tmp=0;
            for(int j=1;j<=min(x,y);j++){
                tmp+=(ll)mu[j]*(x/j)*(y/j);
                tmp%=p;
            }
            ans+=tmp*a[d];
            ans%=p;

        }
        printf("%lld\n", ans);
    }
    return 0;
}

神烦啊QAQ$!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值