Codeforces Round #692 (Div. 1) C. Poman Numbers (贪心)

C. Poman Numbers

题意

给定一个字符串和一个函数 f ( S ) f(S) f(S)

f ( S ) = { 2 p o s ( S [ 1 ] ) ∣ S ∣ = 1 − f ( S ( 1 , m ) ) + f ( S ( m + 1 , ∣ S ∣ ) ) ∣ S ∣ > 1 f(S)=\begin{cases} 2^{pos(S[1])} & |S|=1\\ -f(S(1,m))+f(S(m+1,|S|)) &|S|>1 \end{cases} f(S)={2pos(S[1])f(S(1,m))+f(S(m+1,S))S=1S>1

其中 p o s ( c ) pos(c) pos(c) 表示字母 c c c 相对 a 的位置。

解法
  • 题目可以看作字符串的每个字母都代表着一个值: 2 p o s ( S [ i ] ) 2^{pos(S[i])} 2pos(S[i]) ,然后所有值对字符串的值做正贡献或负贡献;

  • 显然最后一个字母做正贡献,倒数第二个字母做负贡献;

  • 接下来证明前 n − 2 n-2 n2 字母贡献可正可负;

  • 假设最终希望的贡献是 − − − + + − + − + ---++-+-+ ++++ ,那么前面的负贡献可以每次令 m = 1 m=1 m=1 得到,剩下的是 + + − + − + ++-+-+ ++++ ,可以令 m = n − 2 m=n-2 m=n2 ,即 ( − − + − ) − + (--+-)-+ (+)+ ,只需要得到 − − + − --+- +即可,那么问题就可以这样递归解决了。

  • n − 2 n-2 n2 项贡献可正可负,贪心即可。

代码
#pragma region
//#pragma optimize("Ofast")
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
typedef long long ll;
#define tr t[root]
#define lson t[root << 1]
#define rson t[root << 1 | 1]
#define rep(i, a, n) for (int i = a; i <= n; ++i)
#define per(i, a, n) for (int i = n; i >= a; --i)
#pragma endregion
const int maxn = 1e5 + 5;
char s[maxn];
int main() {
    ll n, m;
    scanf("%lld%lld", &n, &m);
    scanf("%s", s + 1);
    m -= (1LL << (s[n] - 'a')) - (1LL << (s[n - 1] - 'a'));
    vector<int> cnt(26);
    rep(i, 1, n - 2) cnt[s[i] - 'a']++;
    for (int i = 25; i >= 0; --i) {
        while (cnt[i]) {
            ll x = m - (1LL << i);
            ll y = m + (1LL << i);
            m = abs(x) < abs(y) ? x : y;
            cnt[i]--;
        }
    }
    puts(m ? "No" : "Yes");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值