【jzoj4194】【Banner】【容斥原理】

56 篇文章 0 订阅

题目大意

给出一个(n+1)*(m+1)的点阵,求有多少种选起点终点(无序点对)使得连线除起点终点外不经过其他点,且长度在给定区间内。

解题思路

观察可知枚举横向x纵向y长度即可求出长度,gcd(x,y)==1时成立,与坐标轴平行的特殊考虑。枚举x即可求出y的取值范围,发现可以算出x有多少取法,每个y对应的取法是等差数列,可以直接求和。
但是我们要求互质,分解枚举的x,发现不同质数的个数有限,可以使用容斥原理解决。

code

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LF double
#define LL long long
#define Min(a,b) ((a<b)?a:b)
#define Max(a,b) ((a>b)?a:b)
#define Fo(i,j,k) for(LL i=j;i<=k;i++)
#define Fd(i,j,k) for(LL i=j;i>=k;i--)
using namespace std;
LL const MxN=1e7;
LL N,M,L,R,B,Pri[20];
LL Calc(LL X,LL Y,LL Z){
    return (X>Y)?0:1ll*(2*M-X-Y+2)*((Y-X)/Z+1)/2%B;
}
int main(){
    freopen("d.in","r",stdin);
    freopen("d.out","w",stdout);
    scanf("%lld%lld%lld%lld%lld",&N,&M,&L,&R,&B);
    LL Mx=Min(N,R),Ans=0,L1,R1,I;
    Fo(i,1,Mx){
        L1=(L>i)?ceil(sqrt(L*L-i*i)):1,R1=Min(M,(long long)(sqrt(R*R-i*i))),I=i; LL Mx=sqrt(i);Pri[0]=0;
        Fo(j,2,Mx)if(I%j==0){
            Pri[++Pri[0]]=j;
            while(I%j==0)I/=j;
        }
        if(I!=1)Pri[++Pri[0]]=I;Mx=(1<<Pri[0])-1;
        Fo(s,0,Mx){
            LL S=s,D=1,Tag=1;
            Fo(j,1,Pri[0]){
                D=(S&1)?D*Pri[j]:D;
                Tag=(S&1)?-Tag:Tag;
                S>>=1;
            }
            Ans=(Ans+1ll*Tag*(N-i+1)*Calc(Max(1ll,ceil(1.0*L1/D))*D,R1/D*D,D))%B;
        }
        LL tt;
        tt++;
    }
    Ans=(1ll*Ans*2+((L==1)?(1ll*N*(M+1)%B+1ll*(N+1)*M%B)%B:0))%B;
    printf("%lld",(Ans+B)%B);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值