洛谷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;
}
标签:std,ch,洛谷,ll,namespace,P2522,miu,sum 来源: https://www.cnblogs.com/lgj-lgj/p/12335060.html