B. Nastya Studies Informatics

知识点:暴力,一个数的因数个数少

题意:求区间[L,R]内有多少对数<a,b>,使得gcd(a,b)==x,lcm(a,b)==y.   其中L,R,a,b都已经给定.  如果<a,b>中a==b只算一种

思路:既然是y的因数,可以在sqrt(y)的时间内处理出所有因数个数t(t很小),暴力t^2

关于因数个数很小的解释: 根据质因数分解唯一定理,每个质因数的幂次不会太大,因子总个数=(k1+1)*(k2+1)-----等等.  因此一个数的因子总个数不会太多.碰到类似和因子有关的内容直接暴力

#include<bits/stdc++.h>
#define PI acos(-1.0)
#define pb push_back
#define F first
#define S second
using namespace std;
typedef long long ll;
const int N=1e5+5;
const int MOD=1e9+7;
//ll a[N],sum[N];
set<pair<ll,ll> >ans;
vector<ll> t;
int main(void){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);

    ll l,r,x,y;
    ll cnt=0;
    cin>>l>>r>>x>>y;
    for(ll i=1;i*i<=y;i++){
        if(y%i==0){
//                cout <<i <<" "<<y/i<<endl;
//            if(i>r||i<l||y/i>r||y/i<l)    continue;在这里判是有问题的...xxxx....
            t.pb(i);
            cnt++;
            if(i!=y/i)  t.pb(y/i);
        }
    }
//    cout <<"cnt="<<cnt<<endl;
//    ll ans=0;
    bool f=false;
    for(auto a:t){
        for(auto b:t){
//            cout <<a <<" "<<b<<" "<<__gcd(a,b)<<endl;
            if(__gcd(a,b)==x&&a*b==x*y&&a>=l&&a<=r&&b>=l&&b<=r){

                ans.insert(make_pair(a,b));
            }
        }
    }
    cout << ans.size()<< endl;
    return 0;
}