zoukankan      html  css  js  c++  java
  • 2^k进制数

    传送门

    题意:

    设 r 是个 (2^k) 进制数,并满足以下条件:

    (1)r 至少是个 2 位的 (2^k) 进制数。

    (2)作为 (2^k) 进制数,除最后一位外, r 的每一位严格小于它右边相邻的那一位。

    (3)将 r 转换为 2 进制数 q 后,则 q 的总位数不超过 w 。

    在这里,正整数 k ( 1 ≤ k ≤ 9 )和 w ( k < w ≤ 30000 )是事先给定的。

    问:满足上述条件的不同的 r 共有多少个?

    此题为NOIP2006第4题

    解法:

    此题官方正解是递推,我们用组合直接推其性质 跑的快多了

    (n=lfloorfrac{w}{k} floor)

    (k|w)时,
    n则表示(2^k)进制数的位数,且每一位数都可以取0到(2^k-1)

    否则
    会多出一个最高位,且最高位取到的数只能是0到(2^{w mod k}-1)

    但我们先考虑最高位为0的情况

    • 则还剩下n位给我们填数

    • 若每一位都要填上数,每个数又不能重复,还要严格按照小到大排序

    • 易得用0到(2^k-1)的数 填n位数的情况有(C^n_{2^k-1})

    • 但是也可以第n位数为0,第n-1位数为0,根据上述结论可以得到这两种分别有(C^{n-1}_{2^k-1} C^{n-2}_{2^k-1})

    • 又因为第2位数不能为0

    • 可得最高位为0的情况下,可取的数有

    • (sum^n_{i=2}C_{2^k-1}^i)

    那么当最高位不为0时

    • 我们可以枚举最高位的数(i=1)(2^{w mod k}-1)

    • 那么还剩数(2^k-i-1)供n个数选择

    • 即最高位为(i)时有(C_{2^k-i-1}^n)

    • 得最高位不为0时有

    • (sum^{2^{w mod k} -1}_{i=1}C_{2^k-i-1}^n)

    则答案为

    (sum^n_{i=2}C_{2^k-1}^i+sum^{2^{w mod k} -1}_{i=1}C_{2^k-i-1}^n)

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<map>
    #define inf 100000000
    #define min(x,y) ((x)<(y)?(x):(y))
    #define max(x,y) ((x)>(y)?(x):(y))
    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define dwn(i,a,b) for(int i=(a);i>=(b);--i)
    using namespace std;
    typedef long long ll;
    const int mod=1e4;
    int k,n,times,p2;
    struct node{
        int arr[60],len;
        node()
        {
            memset(arr,0,sizeof(arr));
            len=0;
        }
        void print()
        {
            printf("%d",arr[len]);
            dwn(i,len-1,0)
            {
                printf("%04d",arr[i]);
            }
            putchar('
    ');
        }
    }c[520],ans;
    node operator +(node a,node b)
    {
        node c;c.len=max(a.len,b.len);int x=0;
        rep(i,0,c.len)
        {
            c.arr[i]=a.arr[i]+b.arr[i]+x;
            x=c.arr[i]/mod;
            c.arr[i]%=mod;
        }
        if(x>0)
            c.arr[++c.len]=x;
        return c;
    }
    node operator *(node a,int b)
    {
        node c;c.len=a.len;ll x=0;
        rep(i,0,c.len)
        {
            c.arr[i]=(1ll*a.arr[i]*b+x)%mod;
            x=(1ll*a.arr[i]*b+x)/mod;
        }
        while(x>0)
        {
            c.arr[++c.len]=x%mod;
            x/=mod;
        }
        return c;
    }
    node operator /(node a,int b)
    {
        node c;c.len=a.len;ll x=0;
        dwn(i,c.len,0)
        {
            c.arr[i]=(a.arr[i]+x*mod)/b;
            x=(a.arr[i]+x*mod)%b;
        }
        dwn(i,c.len,1)
        {
            if(c.arr[i]==0) c.len--;
            else break;
        }
        return c;
    }
    int main()
    {
        scanf("%d%d",&k,&n);
        p2=(1<<k)-1,times=(1<<(n%k))-1;
        c[0].arr[0]=1;
        rep(i,1,min(p2,n/k))
        {
            c[i]=c[i-1]*(p2-i+1)/i;
        }
        rep(i,2,min(p2,n/k))
        {
            ans=ans+c[i];
        }
        if(n/k<=p2)
        {
            c[p2]=c[n/k];
            rep(i,1,times)
            {
                c[p2-i]=c[p2-i+1]*(p2-i+1-n/k)/(p2-i+1);
                ans=ans+c[p2-i];
            }
        }
        ans.print();
        return 0;
    }
    
    
  • 相关阅读:
    面向对象的继承关系体现在数据结构上时,如何表示
    codeforces 584C Marina and Vasya
    codeforces 602A Two Bases
    LA 4329 PingPong
    codeforces 584B Kolya and Tanya
    codeforces 584A Olesya and Rodion
    codeforces 583B Robot's Task
    codeforces 583A Asphalting Roads
    codeforces 581C Developing Skills
    codeforces 581A Vasya the Hipster
  • 原文地址:https://www.cnblogs.com/MYsBlogs/p/10910981.html
Copyright © 2011-2022 走看看