luogu P5596 【XR-4】题 |数学

题目背景

xht37 喜欢分块,以至于对一道不需要分块的题也要分块做。

题目描述

有一个长度为 nn 的序列,xht37 现在想分块维护它。

PinkRabbit 要求他只准将序列分成 PRPR 种长度的块。

NaCly_Fish 要求他只准将序列分成 NFNF 种长度的块。

同一个人可能会要求 xht37 多次相同的块长。

xht37 想同时满足 PinkRabbit 和 NaCly_Fish 要求,只好使用两个人都允许的长度分块。

xht37 想知道,有多少种不同的分块方案,答案对 10 ^ 9 + 7 取模。

输入格式

第一行一个正整数 nn,表示序列的长度。

第二行一个正整数 PRPR,表示 PinkRabbit 要求的分块长度的种类数。

第三行 PRPR 个正整数,表示 PinkRabbit 要求的 PRPR 种分块长度。

第四行一个正整数 NFNF,表示 NaCly_Fish 要求的分块长度的种类数。

第五行 NFNF 个正整数,表示 NaCly_Fish 要求的 NFNF 种分块长度。

输出格式

输出一行一个整数,表示不同分块方案的种类数对 10 ^ 9 + 7取模的值。

说明/提示

对于 100% 的数据,1<=a<=1e8 ,1<=b<=1e15


由上式可得(2x+2y+a)(2x−2y−a)=a^2-4b

然后设m=2x+2y+a,n=2x-2y-a可以对a^2-4b进行分类讨论

枚举n的值,判断是否满足条件

因为m>n必须成立,所以n<=sqrt(a^2-4b)

时间复杂度sqrt(a^2-4b)

#include<cmath>
#include<cstdio>
#include<iostream>
#define ll long long
#define int long long
using namespace std;
signed main(){
    int a,b,ans=0;
    scanf("%lld%lld",&a,&b);
    if((a/2)*(a/2)==b&&!(a%2)){
        puts("inf");
		return 0; 
    }
    ll k=a*a-4*b;
    if(k>0){
        ll k=a*a-4*b;
        for(ll n=1;n*n<=k;n++){
        	int m=k/n;
            if(k%n==0&&n+m>=2*a&&m>=n){
                if((m-n)%4==0&&(n+m-2*a)%4==0){
                    ll x=(n+m-2*a)>>2,y=(m-n)>>2;
                    if(x>=0&&y>=0)ans++; 
                }
            }
        }
    }
    else{
        ll k=4*b-a*a;
        for(ll n=1;n*n<=k;n++){
        	int m=k/n;
             if(k%n==0&&m>=n+2*a){
                if((m-n-2*a)%4==0&&(n+m)%4==0){
                    ll x=(m-n-2*a)>>2,y=(n+m)>>2;
                    if(x>=0&&y>=0)ans++;
                }
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}
posted @ 2019-10-23 20:42  白木偶君  阅读(213)  评论(0编辑  收藏  举报