light1170

我的解法:先将1-1e5的非完全平方放入vector。非完全平方数的质因数分解的数量互质,比如12不是完全平方,2的个数(2个),和3的个数(1个),互质。而36有,2个2,2个3,数量不互质。非完全平方数的次方没有交集。比如2^2*3^6只能是(2*3^3的平方)。这样a,b之间的平方数个数就用1-1e5来二分查找数量。

更简单的做法是找1-1e10的平方数存入vector。再二分。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
//#include <unordered_set>
#define mkp make_pair
#define err cout<<"here"<<endl
using namespace std;
const double EPS=1e-8;
typedef long long lon;
typedef unsigned long long ull;
typedef map<ull,int>::iterator IT;
const lon SZ=2010,SSZ=100010,APB=26,mod=100000007,one=97;
const lon INF=0x7FFFFFFF;
lon n,C[SZ],u[SSZ];
vector<lon> vct;
struct nd{
    lon to,wt;
    nd(lon a=0,lon b=0):to(a),wt(b){}
};

int calc(lon x,lon y)
{
    int lo=0,hi=vct.size();
    for(;lo<hi;)
    {
        int mid=(lo+hi)/2;
        bool ok=pow(vct[mid],x)<=y;
        if(ok)lo=mid+1;
        else hi=mid;
    }
    return lo;
}

lon get_num(lon a,lon b)
{
    lon res=0;
    for(lon j=2;;++j)
    {//cout<<i<<endl;
        if((1LL<<j)>b)break;
        res+=calc(j,b)-calc(j,a-1);
    }
    return res;
}

void init()
{
    lon a,b;
    //cin>>a>>b;
    scanf("%lld%lld",&a,&b);
    if(a>b)swap(a,b);
    lon num=get_num(a,b);
    lon res=C[num];
    printf("%lld\n",res);
    //cout<<num<<endl;
}

void work()
{
    
}

void release()
{
    
}

int main()
{
    //std::ios::sync_with_stdio(0);
    //freopen("d:\\1.txt","r",stdin);
    lon casenum;
    cin>>casenum;
    C[0]=C[1]=1;
    for(int i=2;i<SZ;++i)
    {
        for(int j=0;j<i;++j)
        {
            C[i]+=C[j]*C[i-j-1]%mod;
        }
        C[i]%=mod;
        //cout<<C[i]<<endl;
    }
    C[0]=0;
    memset(u,1,sizeof(u));
    for(int i=2;;++i)
    {
        if(pow(i,2)>SSZ-3)break;
        for(int j=2;;++j)
        {
            if(pow(i,j)>SSZ-3)break;
            int val=pow(i,j);
            u[val]=0;
        }
        //cout<<u[i]<<endl;
    }
    for(int i=2;i<SSZ-5;++i)
    {
        if(u[i])
        {
            vct.push_back(i);
        }
    }
    //cout<<casenum<<endl;
    for(int time=1;time<=casenum;++time)
    //for(lon time=1;cin>>str+1;++time)
    {
        printf("Case %d: ",time);
        init();
        work();
        release();
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/gaudar/p/10849717.html