BZOJ 4174 tty的求助

Posted on 2017-03-02 11:36  ziliuziliu  阅读(266)  评论(0编辑  收藏  举报

重点是要搞清楚取整符号的性质。[(a+b)/c]=(a-a%c)/c+[(a%c+b)/c]

思路应该是首先明白这是一个反演题,然后尝试把最后一个Σ换成易于表达的式子。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 500050
#define mod 998244353
using namespace std;
long long n,m,prime[maxn],tot=0,miu[maxn],ans=0;
double x;
bool vis[maxn];
void get_prime()
{
    miu[1]=1;
    for (long long i=2;i<=maxn-50;i++)
    {
        if (!vis[i]) {vis[i]=true;miu[i]=-1;prime[++tot]=i;}
        for (long long j=1;j<=tot && i*prime[j]<=maxn-50;j++)
        {
            vis[i*prime[j]]=true;
            if (i%prime[j]) miu[i*prime[j]]=-miu[i];
            else {miu[i*prime[j]]=0;break;}
        }
    }
}
long long f_pow(long long a,long long b)
{
    long long ans=1,base=a;
    while (b)
    {
        if (b&1) ans=(ans*base)%mod;
        base=(base*base)%mod;
        b>>=1;
    }
    return ans;
}
long long inv(long long x) {return f_pow(x,mod-2);}
int main()
{
    scanf("%lld%lld%lf",&n,&m,&x);
    get_prime();
    if (n>m) swap(n,m);
    ans=(ans+(n*(n-1)/2)%mod*((m*(m-1)/2)%mod)%mod-m*n%mod+mod)%mod;
    for (long long d=1;d<=n;d++)
    {
        long long a=2*d*(long long)(x/d)+d,b=0;a%=mod;
        for (long long i=1;i<=n/d;i++) {b+=miu[i]*(n/i/d)*(m/i/d)%mod;b=(b+mod)%mod;}
        ans=(ans+a*b%mod)%mod;ans=(ans+mod)%mod;
    }
    printf("%lld\n",ans*inv(2)%mod);
    return 0;
}