首页 > 其他分享 >Solution - Codeforces 1628D2 Game on Sum (Hard Version)

Solution - Codeforces 1628D2 Game on Sum (Hard Version)

时间:2024-10-15 16:11:21浏览次数:5  
标签:frac 于是 Sum Hard Codeforces maxn 考虑 ll mod

首先来考虑 Easy

注意到的是最后输出的答案要求是模意义下的,这说明对于实数二分的做法都已经用不了了。
注意到 \(n, m\le 3000\) 的数据范围,于是一个想法就是考虑 DP 之类的算法。

考虑到 B 选了 \(+ / -\) 实际上就代表着下一轮的 \(m\) 是否会 \(-1\),于是可以设状态为 \(f_{i, j}\) 表示还有 \(i\) 轮,还有 \(j\) 个 \(+\) 要选的最优值。

那么边界值容易知道是 \(f_{i, 0} = 0, f_{i, i} = ik\),即如果只剩 \(-\) 那么肯定是 A 全选 \(0\),如果全剩 \(+\) 那么肯定是 A 全选 \(k\)。
那么就来考虑 \(f_{i, j}(j\in (0, i))\) 的转移,考虑到 A 选了一个 \(x\) 后,B 会选 \(+ / -\),因为 B 想最小,于是 B 选出来的一定是 \(\min\{f_{i - 1, j - 1} + x, f_{i - 1, j} - x\}\)。
因为 A 要最大化,相当于是 \(f_{i, j} = \max\{\min\{f_{i - 1, j - 1} + x, f_{i - 1, j} - x\}\}(x\in [0, k])\)。
于是从函数图象分析,非常显然的是肯定是取 \(x = \frac{f_{i - 1, j} - f_{i - 1, j - 1}}{2}\) 最优,此时有 \(f_{i, j} = \frac{f_{i - 1, j - 1} + f_{i - 1, j}}{2}\)。

其实上面还漏了一步,为什么这个 \(x\) 一定能被选出来?
那么实际上就是说明 \(f_{i - 1, j} - f_{i - 1, j - 1}\le 2k\),这个还是比较显然的,因为再劣也劣不过把 \(-k\) 改为 \(+k\) 的 \(\Delta = 2k\)。

于是 Easy 就做完了,时间复杂度 \(\mathcal{O}(nm)\)。

接下来考虑 Hard

那么一个想法是 DP 转移的值实际上都是有 \(f_{i, i}\) 的边界条件推来的,于是可以对于每个 \((i, i)\) 单独统计对 \((n, m)\) 的贡献。

首先考虑到的是 DP 中从 \(i\to i + 1\) 就会有 \(\frac{1}{2}\) 的系数,所以首先就有个 \(\frac{1}{2^{n - i}}\) 的系数。
其次考虑到 \((i, i)\) 剩下时候就可以任意走 \((+1, +1)\) 或者 \((+1, 0)\),但是不能走到 \((j, j)\)。
但是发现不能走到 \((j, j)\) 是好算的,因这个的充要条件就是走到了 \((i + 1, i + 1)\)。
于是只需要钦定第一步走到是 \((+1, 0)\) 就可以了,方案数为 \(\binom{n - i - 1}{m - i}\)。

于是就在 \(\mathcal{O}(n)\) 的时间复杂度做完了。

注意特判 \(n = m\)。

#include<bits/stdc++.h>
using ll = long long;
constexpr ll mod = 1e9 + 7, inv2 = mod + 1 >> 1;
inline ll qpow(ll a, ll b, ll v = 1) {
   while (b)
      b & 1 && ((v *= a) %= mod), b >>= 1, (a *= a) %= mod;
   return v;
}
const int maxn = 1e6 + 10, N = 1e6;
ll fac[maxn], ifac[maxn], pw[maxn];
inline void init() {
   for (int i = fac[0] = 1; i <= N; i++) fac[i] = fac[i - 1] * i % mod;
   ifac[N] = qpow(fac[N], mod - 2);
   for (int i = N; i; i--) ifac[i - 1] = ifac[i] * i % mod;
   for (int i = pw[0] = 1; i <= N; i++) pw[i] = pw[i - 1] * inv2 % mod;
}
inline ll binom(int n, int m) {return fac[n] * ifac[m] % mod * ifac[n - m] % mod;}
inline void solve() {
   int n, m; ll k; scanf("%d%d%lld", &n, &m, &k);
   if (n == m) return printf("%lld\n", m * k % mod), void();
   ll ans = 0;
   for (int i = 1; i <= m; i++)
      (ans += 1ll * i * k % mod * binom(n - i - 1, m - i) % mod * pw[n - i]) %= mod;
   printf("%lld\n", ans);
}
int main() {
   init();
   int T; scanf("%d", &T);
   for (int id = 1; id <= T; id++) solve();
   return 0;
}

标签:frac,于是,Sum,Hard,Codeforces,maxn,考虑,ll,mod
From: https://www.cnblogs.com/rizynvu/p/18467669

相关文章

  • 「题解」Educational Codeforces Round 170 (Rated for Div. 2)
    before我不想写作业呜呜。A.TwoScreensProblemA.TwoScreensSol&Code理解题意后发现使用复制的方法完成最长公共前缀即可。#include<bits/stdc++.h>typedeflonglongll;typedefstd::pair<int,int>pii;intT;std::strings1,s2;intmain(){scanf("%d"......
  • Educational Codeforces Round 170 (Rated for Div. 2) D.Attribute Checks (没有完全
    算法显然为dp状态设计\(dp_{i,j}\)表示在第\(i\)个获得能力点的地方,之前智慧能力值为\(j\),时的最大分数状态转移显然需要从\(dp_{i-1,j}\)转移而来枚举\(j\in[0,i)\)则有(注意取\(\max\)操作要与自己相比较)设第\(i-1\)个能力点到第\(i\)个能......
  • # Educational Codeforces Round 170 (Rated for Div. 2) 题解D
    EducationalCodeforcesRound170(RatedforDiv.2)题解DD.AttributeChecks链接:Problem-D-Codeforces思路:由于\(m\)还有\(abs(r[i])\)很小,考虑dp因为每个0能对后面多少个check做出贡献是固定的,所以预处理因为我们每次的0的个数是单调不减的所以,我们上一次......
  • Educational Codeforces Round 170 (Rated for Div. 2) C. New Games
    题意转化找一些相邻的数(其中相邻定义为递增序下任意相邻两数差\(\leq1\))求相邻数中,不同数字有\(k\)种,取到数字个数的最大值算法容易想到按顺序排列观察到有点像滑动窗口,考虑用队列维护一个出现不同数字次数为\(k\)的区间,再计算代码来自转载地址voidsolv......
  • Codeforces Educational Codeforces Round 170 (Rated for Div. 2)
    A-TwoScreens大意:    给两个字符串,每次在两个空子符串进行两种操作     1、字符串末尾加一个任意字母    2、一个字符串全部复制给另一个字符串    求得到给定的两个字符串的最小操作数思路:    看最前面有多少相等即可 ......
  • Educational Codeforces Round 170 (Rated for Div. 2)
    目录写在前面A签到B结论C双指针D模拟,差分,DP,结论E计数,DP,F写在最后写在前面比赛地址:https://codeforces.com/contest/2025。妈的不想上学省赛回来昏了一天了。A签到发现最优的操作是先在一个屏幕操作得到最长公共前缀,然后复制到另一方上,再分别操作两方。特判若无公共前......
  • 题解:P10370 「LAOI-4」Mex Tower (Hard ver.)
    ProblemLink「LAOI-4」MexTower(Hardver.)题意给定一个长度为$n$的序列$a$,求序列的$\operatorname{Mex}$值是否大于等于其他所有长度为$n$的自然数序列的$\operatorname{Mex}$值。Solution不难发现,两个数或一个序列的$\operatorname{Mex}$一定是......
  • Codeforces Round 978 (Div. 2) A-D1 题解
    我的同学还在VP,排名马上放声明:不要觉得有subtask的题目只做Easyversion没有意义,从这里也能捞很多分,况且有的时候并不是简单和难的区别,而是考不同的算法A.BustoPénjamo题意有一辆车上面有$r$排座位,每排有$2$个座位,现在共$n$个家庭出行坐公交车,每个家庭$a_i$......
  • 基于Python的自然语言处理系列(26):Get to the Point Summarization
            在本篇文章中,我们将实现经典的"GettothePoint"模型,该模型最初发表于GettothePoint:SummarizationwithPointer-GeneratorNetworks。这是当时最著名的摘要生成模型之一,至今仍有很多人使用其Pointer-Generator架构作为他们模型的一部分。1.模型简介......
  • codeforces round 977 (div.2) C2(访问set的第一个元素,观察数据规律-出现次序,用set记
    解题历程:我首先想到的是等效法,每一次操作可以等效为每次将第一个人抽出放入一组,后面的人往前移,而该组的人就是可以任意放置的人,当b中后面再出现与前一个相同的人时,就不进行操作,当b中出现不同的人时,就看看这组中有没有这个人,有的话就下一个循环,没有的话就看看这个新的人是否按a中......