1. 程式人生 > >Codeforces 914 C. Travelling Salesman and Special Numbers (dp)

Codeforces 914 C. Travelling Salesman and Special Numbers (dp)

Description

The Travelling Salesman spends a lot of time travelling so he tends to get bored. To pass time, he likes to perform operations on numbers. One such operation is to take a positive integer x and reduce it to the number of bits set to 1 in the binary representation of x. For example for number 13 it’s true that

1310=11012 , so it has 3 bits set and 13 will be reduced to 3 in one operation.

He calls a number special if the minimum number of operations to reduce it to 1 is k.

He wants to find out how many special numbers exist which are not greater than n. Please help the Travelling Salesman, as he is about to reach his destination!

Since the answer can be large, output it modulo 10^9 + 7.

Input

The first line contains integer n (1 ≤ n < 2^1000).

The second line contains integer k (0 ≤ k ≤ 1000).

Note that n is given in its binary representation without any leading zeros.

Output

Output a single integer — the number of special numbers not greater than n, modulo 10^9 + 7.

Examples input

110
2

Examples output

3

題意

我們定義一種操作為將一個正整數變化為它二進位制 1 的個數,問在小於等於給定二進位制數的正整數中,有多少個數可以經過 k 次操作變化為 1 。

思路

從題中我們可以看到,一次操作可以將一個數變化為其二進位制 1 的個數,於是我們設 dp[i] 表示二進位制中有 i 個 1 的數需要幾次變化才能到達 1 。

顯然 dp[i] = dp[getNum(i)] + 1 ,其中 getNum 可以得出 i 二進位制 1 的個數。

對於 dp[i] == k-1 的 i ,接下來的工作便是找出小於等於給定數且二進位制 1 的個數為 i 的數的數量,直接用組合數很方便可以求得。

AC 程式碼

#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false);\
    cin.tie(0);\
    cout.tie(0);
using namespace std;
typedef long long LL;
const int mod = 1e9+7;
const int maxn = 1e5+10;

char str[maxn];
LL mul[maxn];
LL inv[maxn];
int dp[maxn];
int len,k;

void init()
{
    mul[0]=1;
    for(int i=1; i<maxn; i++)
        mul[i]=(mul[i-1]*i)%mod;

    inv[0]=inv[1]=1;
    for(int i=2; i<maxn; i++)
        inv[i]=(LL)(mod-mod/i)*inv[mod%i]%mod;
    for(int i=1; i<maxn; i++)
        inv[i]=(inv[i-1]*inv[i])%mod;
}

LL C(int n,int m)
{
    return mul[n]*inv[m]%mod*inv[n-m]%mod;
}

int getNum(int x)
{
    int res = 0;
    while(x)
    {
        res+=x&1;
        x>>=1;
    }
    return res;
}

int call(int x)
{
    int res = 0;
    for(int i=0; i<len; i++)
        if(str[i]-'0')
            res = (res + C(len-i-1,x--))%mod;
    return (res + (x==0))%mod;
}

void solve()
{
    len = strlen(str);
    if(k==0)
        cout<<1<<endl;
    else if(k==1)
        cout<<len-1<<endl;
    else
    {
        int ans = 0;
        for(int i=2; i<=1000; i++)
        {
            dp[i] = dp[getNum(i)] + 1;
            if(dp[i]==k-1)
                ans = (ans + call(i)) % mod;
        }
        cout<<ans<<endl;
    }
}

int main()
{
    IO;
    init();
    cin>>str>>k;
    solve();
    return 0;
}

相關推薦

Codeforces 914 C. Travelling Salesman and Special Numbers dp

Description The Travelling Salesman spends a lot of time travelling so he tends to get bored. To pass time, he likes to perform

Codeforces#458 C.Travelling Salesman and Special Numbers

題目: http://codeforces.com/contest/914/problem/C 分析: 一次操作後,必定變為1000以內的數; 則先暴力處理出1000以內的合法數; 然後遞推出

Codeforces Round #458 (Div. 1 + Div. 2C. Travelling Salesman and Special Numbers

C. Travelling Salesman and Special Numbers time limit per test 1 second memory limit per test 256 megabytes input standard in

Codeforces Round #458 C Travelling Salesman and Special Numbers

題意:給定一種reduce操作(將某數置成其二進位制表示下1的個數),某數reduce到1所需要的操作次數為其步長,給一個二進位制數,要求求出小於該數且步長為k的所有數的個數模1e9+7。 思路:  注意到所有範圍內的數的二進位制表示下1的個數不會超過1000,所以所有數

Codeforces 814 C. An impassioned circulation of affection dp

Description Nadeko’s birthday is approaching! As she decorated the room for the party, a long garland of Dianthus-shaped paper

【TOJ 3242】FatMouse and Java Beansdp

ati sin row med AC inpu box his align 描述 FatMouse is lucky enough for it found a rectangular box in a storehouse which contains his favo

Codeforces Round #162 (Div. 2): D. Good SequencesDP

  題意: 給你n個數字,求出最長相鄰不互質子序列   思路: 設dp[i]表示以第i個數字結尾的最長子序列長度 考慮不互質的兩個數(x,y),它們一定存在相同的質因子 在DP過程中求出R[p]表示p的倍數當前最晚出現的位置,那麼就可以得出d

Codechef : Sereja and Equality/SEAEQ DP

傳送門 題解: 普及組DP。 #include <bits/stdc++.h> using namespace std; const int RLEN=1<<18|1; inl

Codeforces Round #432 (Div. 2) D. Arpa and a list of numbers暴力

esp for int ans logs and codeforce style inf 枚舉質數,判斷是否超過臨界值。臨界值就是將不是因子中不含這個素數的數的個數乘以x和y的較小值,是否小於當前最小值。 #include <algorithm> #inclu

Codeforces】CF 467 C George and Jobdp

++ clas show mes ces -m col scanf tro 題目 傳送門:QWQ 分析 dp基礎題。 $ dp[i][j] $表示前i個數分成j組的最大和。 轉移顯然。 吐槽:做cf題全靠洛谷翻譯茍活。 代碼 1

Codeforces 819 C. Mister B and Beacons on Field 容斥 數學

題意: 有一個座標系,有兩個點a,b座標分別(n,0),(0,m),還有一個任意點c。 問題: a向原點移動,詢問移動過程中有多少位置滿足三點構成的三角形的面積等於S。 a在原點,b向原點移動,詢問移動過程中有多少位置滿足三

codeforces 768 C Jon Snow and his Favourite Number(迴圈節

題意: 有一個長度n的數列,瓊恩有一個喜愛的數x,瓊恩每次去隔一個 數對數列裡的數異或,請問k次操作後數列裡最大的數和最小的數分別是什麼 解題思路: 這種題一般來說操作後的數列是有迴圈節的,然後看到群裡qc爸爸問有沒有迴圈節不是2的例子的時候就更確定了。先去模擬下操作,然

Codeforces 914 C 數位DP+暴力打表+思維

return span 每次 amp bits sin fine inline cout 題意 給出一個二進制數\(n\),每次操作可以將一個整數\(x\)簡化為\(x\)的二進制表示中\(1\)的個數,如果一個數簡化為\(1\)所需的最小次數為\(k\),將這個數叫做特殊

[Codeforces Round #261 (Div. 2) E]Pashmak and GraphDp

solution and other main ems scanf homework max urn Description Pashmak‘s homework is a problem about graphs. Although he always tries

Codefroces 366 C Dima and Saladdp

problem set log tdi const pos mem ref 轉換成 Dima and Salad 題意:一共有n種水果,每種水果都有一個ai, bi,現求一個最大的ai總和,使得ai之和/對應的bi之和的值等於K。 題解:將bi轉換成偏移量,只要偏移到起點位

Codeforces】CF 5 C Longest Regular Bracket Sequencedp

ont ref urn 左右 namespace 連續 %d pan tro 題目 傳送門:QWQ 分析 洛谷題解裏有一位大佬講的很好。 就是先用棧預處理出可以匹配的左右括號在數組中設為1 其他為0 最後求一下最長連續1的數量。 代碼

*【CodeForces - 214D 】Numbers dp,組合數學

題幹: Furik loves writing all sorts of problems, especially such that he can't solve himself. You've got one of his problems, the one Furik gave to

CodeForces - 258D:Little Elephant and Broken Sorting概率DP

題意:長度為n的排列,m次交換xi, yi,每個交換x,y有50%的概率不發生,問逆序數的期望  。n, m <= 1000 思路:我們只用維護大小關係,dp[i][j]表示位置i的數比位置j的數大的概率。 那麼每次交換x和y。  假設x<y,那麼區間就有三種: 

Codeforces 689C. Mike and Chocolate Thieves二分

題目連結:http://codeforces.com/contest/689/problem/C 題意:說實話,這個題的意思我愣了看了十多遍沒看懂,最後還是看的別人的題解明白的。        意思就是:有4個賊,他們共用一個容量為n的揹包,他們偷的東

Codeforces Round #522 div2 C、E題解DP

題目連結: C. Playing Piano 題意: 給一個序列,讓你構造一個相等長度的序列,構造的序列中每個元素的取值範圍都為[1,5]。 構造要求: 1. 若原序列a[i]==a[i+1],那麼構造的序列b[i]!=b[i+1]; 2. 若原序列a[i]>a[i