zoukankan      html  css  js  c++  java
  • 【贪心/Trie】【CF1083B】 The Fair Nut and Strings

    Description

    (k) 个长度为 (n) 的只含 (a)(b) 字符串,并不知道它们具体是多少,只知道它们的字典序不小于字符串 (A),同时不大于字符串 (B)。定义一个字符串是合法的当且仅当它是这 (k) 个字符串之一的前缀(如果它是多个串的前缀那么只计算一次)。求合法的字符串最大可能是多少

    Input

    第一行是两个整数 (n)(k)

    下面两行,第一行是长度为 (n) 的字符串 (A),第二行是长度为 (n) 的字符串 (B)

    Output

    输出一个数代表答案。

    Hint

    (1~leq~n~leq~5~ imes~10^5~,~1~leq~k~leq~10^9)

    Solution

    我们考虑假如对这 (k) 个字符串建出一棵Trie树,那么显然一个节点对应一个合法的字符串,答案即为树上节点个数。于是我们的问题即被转化为了最大化Trie树上的节点个数。考虑在一个节点,在合法的条件下孩子数为 (2) 的答案显然不劣于孩子数为 (1) 的答案。于是我们依照此按照层数进行贪心,尽可能的多分节点即可。考虑因为最后一层的节点最多有 (k) 个,所以当算到一层的节点数不小于 (k) 时,后面就无需枚举,直接分配给每层 (k) 个节点计算答案即可。

    Code

    #include <cstdio>
    #include <algorithm>
    #ifdef ONLINE_JUDGE
    #define freopen(a, b, c)
    #endif
    #define rg register
    #define ci const int
    #define cl const long long
    
    typedef long long int ll;
    
    namespace IPT {
    	const int L = 1000000;
    	char buf[L], *front=buf, *end=buf;
    	char GetChar() {
    		if (front == end) {
    			end = buf + fread(front = buf, 1, L, stdin);
    			if (front == end) return -1;
    		}
    		return *(front++);
    	}
    }
    
    template <typename T>
    inline void qr(T &x) {
    	rg char ch = IPT::GetChar(), lst = ' ';
    	while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
    	while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
    	if (lst == '-') x = -x;
    }
    
    template <typename T>
    inline void ReadDb(T &x) {
    	rg char ch = IPT::GetChar(), lst = ' ';
    	while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
    	while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
    	if (ch == '.') {
    		ch = IPT::GetChar();
    		double base = 1;
    		while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
    	}
    	if (lst == '-') x = -x;
    }
    
    namespace OPT {
    	char buf[120];
    }
    
    template <typename T>
    inline void qw(T x, const char aft, const bool pt) {
    	if (x < 0) {x = -x, putchar('-');}
    	rg int top=0;
    	do {OPT::buf[++top] = x % 10 + '0';} while (x /= 10);
    	while (top) putchar(OPT::buf[top--]);
    	if (pt) putchar(aft);
    }
    
    const int maxn = 500010;
    
    ll n, k, ans;
    char MU[maxn], CU[maxn];
    
    int main() {
    	freopen("1.in", "r", stdin);
    	qr(n); qr(k);
    	do MU[1] = IPT::GetChar(); while ((MU[1] > 'z') || (MU[1] < 'a'));
    	for (rg int i = 2; i <= n; ++i) MU[i] = IPT::GetChar();
    	do CU[1] = IPT::GetChar(); while ((CU[1] > 'z') || (CU[1] < 'a'));
    	for (rg int i = 2; i <= n; ++i) CU[i] = IPT::GetChar();
    	ll pre = 1;
    	for (rg int i = 1; i <= n; ++i) {
    		pre <<= 1;
    		if (MU[i] == 'b') --pre;
    		if (CU[i] == 'a') --pre;
    		if (pre >= k) {
    			ans += 1ll * k * (n - i + 1);
    			break;
    		}
    		ans += pre;
    	}
    	qw(ans, '
    ', true);
    	return 0;
    }
    
  • 相关阅读:
    流光shader 和 流光+扭曲shader
    unity3d android动态更新dll
    Shader之溶解效果的几种实现方法
    我的第一个法线贴图
    windows 函数
    MFC 消息框
    C++ MFC棋牌类小游戏day1
    C++STL 预定义函数对象和函数适配器
    C++STL 函数对象和谓词
    C++STL 算法
  • 原文地址:https://www.cnblogs.com/yifusuyi/p/10235368.html
Copyright © 2011-2022 走看看