阿里云秘钥池
對于每個正整數?nn,我們定義它的?pp?進制表示?由?mm?個非負整數?a_1, a_2, \cdots, a_ma?1??,a?2??,?,a?m???組成,并且這些數字滿足?\displaystyle n = \sum_{i = 1}^{m}{a_i p^{i - 1}}n=?i=1?∑?m??a?i??p?i?1??,以及?0 \leq a_i < p\ (i = 1, 2, \cdots, m - 1)0≤a?i??<p?(i=1,2,?,m?1)?和?1 \leq a_m < p1≤a?m??<p。
在阿里云臺上,用戶登錄的秘鑰都是由一個正整數組成。一個可被用作秘鑰的正整數?nn,它的?pp?進制表示需要滿足?1 \leq a_i < p\ (i = 1, 2, \cdots, m)1≤a?i??<p?(i=1,2,?,m)?且?\gcd(a_i, a_{i + 1}) = 1\ (i = 1, 2, \cdots, m - 1)gcd(a?i??,a?i+1??)=1?(i=1,2,?,m?1)。比如當?p = 10p=10?時,6161?是一個合法秘鑰,32163216?也是;但是當?p = 100p=100?時,6161?依舊是一個合法秘鑰,32163216?卻不是。
給出正整數?L, RL,R?和?pp,請你統計滿足?L \leq n \leq RL≤n≤R?并且?nn?是一個合法秘鑰的正整數?nn?的數量。
輸入格式
第一行包含一個正整數?T(1 \leq T \leq 10^3)T(1≤T≤10?3??),表示有?TT?組測試數據。
接下來依次給出每組測試數據,每組測試數據僅一行,包含三個正整數?L, R(1 \leq L \leq R \leq 10^{18})L,R(1≤L≤R≤10?18??)?和?p(2 \leq p \leq 10^5)p(2≤p≤10?5??)?,含義見題目描述。
保證不超過?5050?組數據滿足?p > 10^3p>10?3??。
輸出格式
對于每組數據輸出一行,包含一個整數,表示滿足條件的數字數量。
樣例輸入
4 5 7 9 1 100 2 1 100 5 2017 2121 10樣例輸出
3 6 41 10分析:考慮第一次最高位比原數小的,后面的信息可以直接用莫比烏斯得到;
這樣依次按位枚舉即可;
代碼: #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <bitset> #include <map> #include <queue> #include <stack> #include <vector> #include <cassert> #include <ctime> #define rep(i,m,n) for(i=m;i<=(int)n;i++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define sys system("pause") #define ls rt<<1 #define rs rt<<1|1 #define all(x) x.begin(),x.end() const int maxn=1e5+10; const int N=2e2+10; using namespace std; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qmul(ll p,ll q,ll mo){ll f=0;while(q){if(q&1)f=(f+p)%mo;p=(p+p)%mo;q>>=1;}return f;} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p%mod;p=p*p%mod;q>>=1;}return f;} int n,m,k,t,p[maxn],mo[maxn],phi[maxn],cnt,num[20]; bool vis[maxn]; vector<ll>ret[maxn],sum[maxn]; void init() {mo[1]=1;phi[1]=1;for(int i=2;i<=maxn-10;i++){if(!vis[i]){mo[i]=-1;phi[i]=i-1;p[cnt++]=i;}for(int j=0;j<cnt&&(ll)i*p[j]<=maxn-10;j++){vis[i*p[j]]=true;if(i%p[j]==0){mo[i*p[j]]=0;phi[i*p[j]]=phi[i]*p[j];break;}mo[i*p[j]]=-mo[i];phi[i*p[j]]=phi[i]*(p[j]-1);}} } void build(int len,int bs) {int i,j,k;rep(i,0,len)ret[i].resize(bs),sum[i].resize(bs);rep(i,1,bs-1)ret[1][i]=1,sum[1][i]=0;rep(i,1,bs-1){for(j=i;j<bs;j+=i)sum[1][i]+=ret[1][j];}rep(i,2,len){for(j=1;j<bs;j++)ret[i][j]=0,sum[i][j]=0;for(j=1;j<bs;j++){for(k=j;k<bs;k+=j){ret[i][k]+=mo[j]*sum[i-1][j];}}for(j=1;j<bs;j++){for(k=j;k<bs;k+=j){sum[i][j]+=ret[i][k];}}} } ll gao(ll x,int bs,int tp) {int pos=0;while(x)num[++pos]=x%bs,x/=bs;if(tp)build(pos,bs);ll ans=0;int i,j;rep(i,1,pos-1)rep(j,1,bs-1)ans+=ret[i][j];for(i=pos;i>=1;i--){for(j=1;j<num[i];j++){if(i==pos||__gcd(num[i+1],j)==1)ans+=ret[i][j];}if(num[i]==0||(i!=pos&&__gcd(num[i],num[i+1])!=1))break;}return ans; } int main() {int i,j;init();scanf("%d",&t);while(t--){ll p,q;scanf("%lld%lld%d",&p,&q,&m);printf("%lld\n",gao(q+1,m,1)-gao(p,m,0));}return 0; }
轉載于:https://www.cnblogs.com/dyzll/p/7356617.html
總結
- 上一篇: C++ 系列:extern
- 下一篇: @property与@synthesiz