Codeforces Round #392 (Div. 2) F. Geometrical Progression(数学)

来源:互联网 发布:nginx 菜鸟教程 编辑:程序博客网 时间:2024/06/07 08:31

题意

求在给定区间内的长度为n的等比数列个数,比要大于1,可以是分数

思路

题解总是能把复杂的问题转化成简单的,然而我就是想不到
因为n已经确定,如果枚举首项和末项,则首项应该是公比分母的倍数,即an=(a1)q,q=xn1yn1,枚举x和y,即可求出可能的首项和末项的个数

  • b=a1yn1
  • a1=byn1
  • an=bxn1
  • lbyn1<bxn1r
  • lyn1brxn1

b的个数就是可能的首项和末项的个数
此外,这题的数据范围十分奇葩,动不动就爆int,一言不合就RE

代码

#include <bits/stdc++.h>#define mem(a,b) memset(a,b,sizeof(a))#define rep(i,a,b) for(int i=a;i<b;i++)#define debug(a) printf("a =: %d\n",a);const int INF=0x3f3f3f3f;const int maxn=3e5+50;const int Mod=1000000007;const double PI=acos(-1);typedef long long ll;typedef unsigned int ui;using namespace std;ll pows[maxn];ll gcd(ll a,ll b){    return b==0? a:gcd(b,a%b);}ll qPow(ll x,ll n){    ll ret=1;    while(n){        if(n&1) ret=ret*x;        if(x>1e8 || ret>1e8) return INF;        x=x*x;        n>>=1;    }    return ret;}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);#endif    int n,l,r;    while(~scanf("%d %d %d",&n,&l,&r)){        ll ans=0;        if(n==1) ans=r-l+1;        else if(n==2) ans=(ll)(r-l+1)*(r-l);        else{            int lim= (int) (exp((long double)log(r) / (n - 1)) + 10);            for(int i=1;i<=lim;i++) {                pows[i]=qPow(i,n-1);            }            for(int i=1;i<lim;i++)                for(int j=i+1;j<lim;j++){                    if(gcd(i,j)==1){                        if(l*pows[j]/pows[i]>r) continue;                        ll tmp=r/pows[j]-(l-1)/pows[i];                        if(tmp>0) ans+=tmp;                    }                }            ans<<=1;        }        cout<<ans<<endl;    }    return 0;}
0 0
原创粉丝点击