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
  • 相关阅读:
    Redis主从,集群部署及迁移
    Nginx跨域了解及模拟和解决
    app管理平台 app-host
    FastDFS文件系统使用经验
    FastDFS文件系统迁移和数据恢复
    从单体架构到微服务架构演进
    配置中心之Nacos简介,使用及Go简单集成
    从单体应用到微服务开发旅程
    写DockerFile的一些技巧
    QPS,TPS,并发用户数,吞吐量关系
  • 原文地址:https://www.cnblogs.com/zxyqzy/p/10050745.html
Copyright © 2011-2022 走看看