我的解法:先将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; }