• 阿里云秘钥池


    对于每个正整数 nn,我们定义它的 pp 进制表示 由 mm 个非负整数 a_1, a_2, cdots, a_ma1​​,a2​​,,am​​ 组成,并且这些数字满足 displaystyle n = sum_{i = 1}^{m}{a_i p^{i - 1}}n=i=1m​​ai​​pi1​​,以及 0 leq a_i < p (i = 1, 2, cdots, m - 1)0ai​​<p (i=1,2,,m1) 和 1 leq a_m < p1am​​<p。

    在阿里云台上,用户登录的秘钥都是由一个正整数组成。一个可被用作秘钥的正整数 nn,它的 pp 进制表示需要满足 1 leq a_i < p (i = 1, 2, cdots, m)1ai​​<p (i=1,2,,m) 且 gcd(a_i, a_{i + 1}) = 1 (i = 1, 2, cdots, m - 1)gcd(ai​​,ai+1​​)=1 (i=1,2,,m1)。比如当 p = 10p=10 时,6161 是一个合法秘钥,32163216 也是;但是当 p = 100p=100 时,6161 依旧是一个合法秘钥,32163216 却不是。

    给出正整数 L, RL,R 和 pp,请你统计满足 L leq n leq RLnR 并且 nn 是一个合法秘钥的正整数 nn 的数量。

    输入格式

    第一行包含一个正整数 T(1 leq T leq 10^3)T(1T103​​),表示有 TT 组测试数据。

    接下来依次给出每组测试数据,每组测试数据仅一行,包含三个正整数 L, R(1 leq L leq R leq 10^{18})L,R(1LR1018​​) 和 p(2 leq p leq 10^5)p(2p105​​) ,含义见题目描述。

    保证不超过 5050 组数据满足 p > 10^3p>103​​。

    输出格式

    对于每组数据输出一行,包含一个整数,表示满足条件的数字数量。

    样例输入

    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
    ",gao(q+1,m,1)-gao(p,m,0));
        }
        return 0;
    }
  • 相关阅读:
    几种编辑器的markdown-toc生成目录在github上的表现
    Docker 镜像文件的导入和导出
    Python 的 os 与 sys 模块
    IPython 自动重载魔术
    一种新的python局部调试手法
    Python 动态从文件中导入类或函数的方法
    python2中新式类和经典类的多重继承调用顺序
    Python运行目录或压缩文件
    子类化内置类型
    Django 数据库访问性能优化
  • 原文地址:https://www.cnblogs.com/dyzll/p/7356617.html
Copyright © 2020-2023  润新知