码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ4407]于神之怒加强版

时间:2018-01-10 23:54:30      阅读:314      评论:0      收藏:0      [点我收藏+]

标签:sample   void   bre   blog   const   problem   break   min   fas   

题面戳我
Description
给下N,M,K.求
\[\sum_{i=1}^{n}\sum_{j=1}^{m}\gcd(i,j)^k\quad(mod\quad1e9+7)\]
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

sol

首先单组数据\(O(n)\)的都会噻,就不讲了。(就是内外数论分块\(O(\sqrt n*\sqrt n)=O(n)\)的那种)
这种方法化到最后的答案式应该是
\[ans=\sum_{d=1}^{n}d^k\sum_{i=1}^{n/d}\mu(i)\lfloor\frac n{di}\rfloor\lfloor\frac m{di}\rfloor\]
我们现在令\(T=di\),然后考虑分别计算每一个\(\lfloor\frac nT\rfloor\lfloor\frac mT\rfloor\)对答案的贡献
\[ans=\sum_{T=1}^{n}\lfloor\frac nT\rfloor\lfloor\frac mT\rfloor*\sum_{d|T}d^k\mu(\frac Td)\]
(手玩一下发现就是这样的)
前面那一坨显然还是\(O(\sqrt)\)分块,后面那一坨发现是一个狄利克雷卷积的形式,就是说它还是一个积性函数。线性筛出来后维护一个前缀和即可。

code

我不会说我因为ans没有清零WA了两次的

#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
const ll N = 5000005;
const ll maxn = 5000000;
const ll mod = 1e9 + 7;
ll gi()
{
    ll x=0,w=1;char ch=getchar();
    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if (ch=='-') w=0,ch=getchar();
    while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return w?x:-x;
}
ll fastpow(ll a,ll b)
{
    ll s=1;
    while (b)
    {
        if (b&1) s=s*a%mod;
        a=a*a%mod;b>>=1;
    }
    return s;
}
ll t,k,n,m,pri[N],tot,zhi[N],low[N],h[N],ans;
void Mobius()
{
    zhi[1]=h[1]=low[1]=1;
    for (ll i=2;i<=maxn;i++)
    {
        if (!zhi[i]) low[i]=pri[++tot]=i,h[i]=(fastpow(i,k)-1+mod)%mod;
        for (ll j=1;j<=tot&&i*pri[j]<=maxn;j++)
        {
            zhi[i*pri[j]]=1;
            if (i%pri[j]==0)
            {
                low[i*pri[j]]=low[i]*pri[j];
                if (low[i]==i)
                    h[i*pri[j]]=h[i]*(h[pri[j]]+1)%mod;
                else
                    h[i*pri[j]]=h[i/low[i]]*h[low[i]*pri[j]]%mod;
                break;
            }
            low[i*pri[j]]=pri[j];
            h[i*pri[j]]=h[i]*h[pri[j]]%mod;
        }
    }
    for (ll i=1;i<=maxn;i++) h[i]=(h[i]+h[i-1])%mod;
}
int main()
{
    t=gi();k=gi();
    Mobius();
    while (t--)
    {
        n=gi();m=gi();ans=0;
        if (n>m) swap(n,m);
        ll i=1;
        while (i<=n)
        {
            ll j=min(n/(n/i),m/(m/i));
            ans=(ans+(h[j]-h[i-1]+mod)%mod*((n/i)*(m/i)%mod)%mod)%mod;
            i=j+1;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

[BZOJ4407]于神之怒加强版

标签:sample   void   bre   blog   const   problem   break   min   fas   

原文地址:https://www.cnblogs.com/zhoushuyu/p/8261241.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!