zoukankan      html  css  js  c++  java
  • CF431D Random Task 二分+数位dp

    One day, after a difficult lecture a diligent student Sasha saw a graffitied desk in the classroom. She came closer and read: "Find such positive integer n, that among numbers n + 1, n + 2, ..., n there are exactly m numbers which binary representation contains exactly k digits one".

    The girl got interested in the task and she asked you to help her solve it. Sasha knows that you are afraid of large numbers, so she guaranteed that there is an answer that doesn't exceed 1018.

    Input

    The first line contains two space-separated integers, m and k (0 ≤ m ≤ 1018; 1 ≤ k ≤ 64).

    Output

    Print the required number n (1 ≤ n ≤ 1018). If there are multiple answers, print any of them.

    Examples
    Input
    Copy
    1 1
    Output
    Copy
    1
    Input
    Copy
    3 2
    Output
    Copy
    5

    抱歉,我太菜了,只会二分来数位dp解决;
    貌似有题解是用组合数学解决的,orz ;
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<map>
    #include<set>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<ctime>
    #include<deque>
    #include<stack>
    #include<functional>
    #include<sstream>
    
    //#include<cctype>
    //#pragma GCC optimize("O3")
    using namespace std;
    #define maxn 1000005
    #define inf 0x3f3f3f3f
    #define INF 9999999999
    #define rdint(x) scanf("%d",&x)
    #define rdllt(x) scanf("%lld",&x)
    #define rdult(x) scanf("%lu",&x)
    #define rdlf(x) scanf("%lf",&x)
    #define rdstr(x) scanf("%s",x)
    typedef long long  ll;
    typedef unsigned long long ull;
    typedef unsigned int U;
    #define ms(x) memset((x),0,sizeof(x))
    const long long int mod = 1e9 + 7;
    #define Mod 1000000000
    #define sq(x) (x)*(x)
    #define eps 1e-3
    typedef pair<int, int> pii;
    #define pi acos(-1.0)
    //const int N = 1005;
    #define REP(i,n) for(int i=0;i<(n);i++)
    
    inline ll rd() {
    	ll x = 0;
    	char c = getchar();
    	bool f = false;
    	while (!isdigit(c)) {
    		if (c == '-') f = true;
    		c = getchar();
    	}
    	while (isdigit(c)) {
    		x = (x << 1) + (x << 3) + (c ^ 48);
    		c = getchar();
    	}
    	return f ? -x : x;
    }
    
    ll gcd(ll a, ll b) {
    	return b == 0 ? a : gcd(b, a%b);
    }
    ll sqr(ll x) { return x * x; }
    
    /*ll ans;
    ll exgcd(ll a, ll b, ll &x, ll &y) {
    	if (!b) {
    		x = 1; y = 0; return a;
    	}
    	ans = exgcd(b, a%b, x, y);
    	ll t = x; x = y; y = t - a / b * y;
    	return ans;
    }
    */
    
    
    
    ll qpow(ll a, ll b, ll c) {
    	ll ans = 1;
    	a = a % c;
    	while (b) {
    		if (b % 2)ans = ans * a%c;
    		b /= 2; a = a * a%c;
    	}
    	return ans;
    }
    /*
    int n, m;
    int st, ed;
    struct node {
    	int u, v, nxt, w;
    }edge[maxn<<1];
    
    int head[maxn], cnt;
    
    void addedge(int u, int v, int w) {
    	edge[cnt].u = u; edge[cnt].v = v; edge[cnt].w = w;
    	edge[cnt].nxt = head[u]; head[u] = cnt++;
    }
    
    int rk[maxn];
    
    int bfs() {
    	queue<int>q;
    	ms(rk);
    	rk[st] = 1; q.push(st);
    	while (!q.empty()) {
    		int tmp = q.front(); q.pop();
    		for (int i = head[tmp]; i != -1; i = edge[i].nxt) {
    			int to = edge[i].v;
    			if (rk[to] || edge[i].w <= 0)continue;
    			rk[to] = rk[tmp] + 1; q.push(to);
    		}
    	}
    	return rk[ed];
    }
    int dfs(int u, int flow) {
    	if (u == ed)return flow;
    	int add = 0;
    	for (int i = head[u]; i != -1 && add < flow; i = edge[i].nxt) {
    		int v = edge[i].v;
    		if (rk[v] != rk[u] + 1 || !edge[i].w)continue;
    		int tmpadd = dfs(v, min(edge[i].w, flow - add));
    		if (!tmpadd) { rk[v] = -1; continue; }
    		edge[i].w -= tmpadd; edge[i ^ 1].w += tmpadd; add += tmpadd;
    	}
    	return add;
    }
    ll ans;
    void dinic() {
    	while (bfs())ans += dfs(st, inf);
    }
    */
    
    ll dp[100][100], m;
    int num[100], len, k;
    
    ll dfs(int pos, int limit, int sum) {
    	if (pos < 0)return sum == k;
    	if (!limit&&dp[pos][sum] != -1)return dp[pos][sum];
    	ll ans = 0;
    	int up = limit ? num[pos] : 1;
    	for (int i = 0; i <= up; i++) {
    		ans += dfs(pos - 1, limit&&i == up, sum + (i == 1));
    	}
    	if (!limit)dp[pos][sum] = ans;
    	return ans;
    }
    
    ll sol(ll x) {
    	len = 0;
    	while (x) {
    		num[len++] = x % 2; x /= 2;
    	}
    	return dfs(len - 1, 1, 0);
    }
    
    int main()
    {
    	//ios::sync_with_stdio(0);
    	//memset(head, -1, sizeof(head));
    	while (cin >> m >> k) {
    		ll l = 1, r = 1000000000000000000;
    		memset(dp, -1, sizeof(dp));
    		while (l <= r) {
    			ll mid = (l + r) / 2;
    			ll res = sol(2 * mid) - sol(mid);
    			if (res == m) {
    				l = mid; break;
    			}
    			else if (res < m)l = mid + 1;
    			else r = mid - 1;
    		}
    		cout << l << endl;
    	}
        return 0;
    }
    
    
    
    EPFL - Fighting
  • 相关阅读:
    java将汉语转换为拼音工具类
    Maven 参数说明
    tcp socket的backlog参数
    Java 运行中jar包冲突,定位使用哪个jar包
    Java CMS GC
    数据仓库
    compareTo
    java程序性能分析之thread dump和heap dump
    npm 与 package.json 快速入门教程
    基本 Java Bean
  • 原文地址:https://www.cnblogs.com/zxyqzy/p/10050745.html
Copyright © 2011-2022 走看看