题意
在 16 16 16进制下, [ 1 , n ] [1,n] [1,n]进制位上出现 k k k种不同数的个数。
思路
显然数位 d p dp dp,此种题一般用状压维护状态,然后就裸了。
code
// Problem: F - Digits Paradise in Hexadecimal
// Contest: AtCoder - AtCoder Beginner Contest 194
// URL: https://atcoder.jp/contests/abc194/tasks/abc194_f
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
// Date: 2021-03-09 12:52:11
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=2e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define IOS ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\n",a[n]);
}
char s[N];
int a[N],n,k;
ll dp[N][17][2][2];
int c[1<<17];
int f(int x){
return c[x];
}
ll dfs(int x,int st,bool li=true,bool lead=true){
int mx;
if(c[st]>k) return 0;
if(x==n) return c[st]==k;
ll & ans=dp[x][c[st]][li][lead];
if(~ans) return ans;
ans=0;
mx=li?a[x]:15;
for(int i=0;i<=mx;i++)
ans=(ans+dfs(x+1,(!i&&lead)?st:(st|1<<i),li&(i==mx),lead&(!i)))%mod;
return ans;
}
int main(){
for(int i=1;i<1<<17;i++) c[i]=c[i&(i-1)]+1;
mst(dp,-1);
scanf("%s%d",s,&k);
n=strlen(s);
for(int i=0;i<n;i++)
a[i]=isdigit(s[i])?s[i]-'0':s[i]-'A'+10;
printf("%lld\n",dfs(0,0));
return 0;
}