2017.10.24 T3 2009
樣例數據
輸入
2
2 3
2 2
輸出
3
2
分析:這是一道數論題
1、當a爲奇數時,b一定爲奇數。
這是因爲b=2x+1所以說a前面的2x次方都模成了1,即
以此類推,
可以得到
2、當a爲偶數時,b一定爲偶數。
b>=n時,則
b
時間複雜度O(
如果打表也是可以找到奇數的情況的規律的,偶數就看造化了。
明明給了30%的檔讓我們直接枚舉、快速冪、判斷,但是都沒有人能拿滿……卡常數卡得也是沒誰了。
代碼
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#include<queue>
#include<set>
using namespace std;
int getint()
{
int sum=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());
if(ch=='-')
{
f=-1;
ch=getchar();
}
for(;isdigit(ch);ch=getchar())
sum=(sum<<3)+(sum<<1)+ch-48;
return sum*f;
}
int T,a,n,ans;
int mi[35];
long long ksm(long long x,long long y)
{
long long res=1;
for(;y>=1;x=x*x%mi[n],y=(y>>1))
if(y&1)
res=res*x%mi[n];
return res;
}
int main()
{
freopen("math.in","r",stdin);
freopen("math.out","w",stdout);
mi[0]=1;
for(int i=1;i<=30;++i)
mi[i]=mi[i-1]*2;
T=getint();
while(T--)
{
ans=0;
a=getint(),n=getint();
if(a%2==1)//奇數
cout<<1<<'\n';
else//偶數
{
long long x,y;
for(int i=2;i<=n;i+=2)//n以內直接暴力快速冪
{
x=ksm(a,i);
y=ksm(i,a);
if(x==y)
ans++;
}
if(n%a==0)//大於n(爲什麼要if、else?這只是是向上取整操作寫得醜而已)
{
ans+=mi[n]/mi[n/a];//1<=b<=2^n,所以在這個範圍內找2^(n/a)的倍數
ans-=n/mi[n/a];//前提是b>=n,所以在n以內的要去掉
}
else
{
ans+=mi[n]/mi[n/a+1];
ans-=n/mi[n/a+1];
}
cout<<ans<<'\n';
}
}
return 0;
}
本題結。