洛谷P2522

题目链接

\(Solution:\)

建议先写这道以获得双倍经验
所以在它的基础上加一个前缀和即可

\(Code:\)

#include<bits/stdc++.h>
using namespace std;
namespace my_std
{
    typedef long long ll;
    #define fr(i,x,y) for(ll i=(x);i<=(y);i++)
    #define pfr(i,x,y) for(ll i=(y);i>=(x);i--)
    inline ll read()
    {
        ll sum=0,f=1;
        char ch=0;
        while(!isdigit(ch))
        {
            if(ch=='-') f=-1;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            sum=(sum<<1)+(sum<<3)+(ch^48);
            ch=getchar();
        }
        return sum*f;
    }
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-');
            x=-x;
        }
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
}
using namespace my_std;
const ll N=5e4+50,hahaha=50000;
ll miu[N],sum[N],pri[N],mark[N],tot;
inline void cal_miu()
{
    miu[1]=1;
    for(ll i=2;i<=hahaha;i++)
    {
        if(!mark[i])pri[++tot]=i,miu[i]=-1;
        for(ll j=1;j<=tot&&i*pri[j]<=hahaha;j++)
        {
            mark[i*pri[j]]=1;
            if(i%pri[j]==0){miu[i*pri[j]]=0;break;}
            else miu[i*pri[j]]=-miu[i];
        }
    }
    for(ll i=1;i<=hahaha;i++)
    {
        sum[i]=sum[i-1]+miu[i];
    }
}
inline ll solve(ll n,ll m)
{
    if(n>m)swap(n,m);
    ll ans=0,pos;
    for(ll i=1;i<=n;i=pos+1)
    {
        pos=min(n/(n/i),m/(m/i));
        ans+=(sum[pos]-sum[i-1])*(n/i)*(m/i);
    }
    return ans;
}
int main(void)
{
    cal_miu();
    ll qwq=read();
    while(qwq--)
    {
        ll a=read(),b=read(),c=read(),d=read(),k=read();
        a--;c--;
        int ans=solve(a/k,c/k)+solve(b/k,d/k)-solve(a/k,d/k)-solve(b/k,c/k);
        write(ans);
        putchar('\n');
    }
    return 0;
}
上一篇:MATLAB实例:二元高斯分布图


下一篇:深入详解美团点评CAT跨语言服务监控(四)服务端消息分发