1 条题解
-
0
自动搬运
来自洛谷,原作者为

green_orange
Coding...搬运于
2025-08-24 22:29:40,当前版本为作者最后更新于2021-03-07 14:39:48,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
USACO 2021 Feb T3 Count the Cows G
分析
首先转化题意,分析题中所给出的 和 :
对于向下取整,我们所拥有的技巧相对较少,我们不妨将其写成如下形式:
其中 ,那么我们所分析的条件可转化为 之间的关系。
接下来分析 的性质
我们观察到对于不同的 值, 的系数始终是 的次幂,而题目中所给的关系中出现了对于 的余数,这启发我们将 中再提出一个 来。那么有
题目中的关系可转化为 。
我们发掘出了对于单一的 其具有的性质,考虑对于所有的
展开上式
我们发现有大量 的次幂,这启发我们尝试将 也写成 的次幂相加的形式
题目所给关系转化为 。
根据我们的经验,我们发现上式中的形式就是 的三进制,要求转化为 三进制下每一位关于 同余。
这个结论对我们来说大有脾益,那么,我们就是求有多少的 满足 与 三进制每一位下关于 同余。我们可以很容易联想到数位DP, 设状态为当前DP到多少位,, 的更低位在做加法时有没有进位 ,由高位向低位DP即可,时间复杂度 。
实现
#include <bits/stdc++.h> using namespace std; const static int mlg = 40; #define int long long int f[mlg][2][2][2]; bool vis[mlg][2][2][2]; int Ab[mlg], Bb[mlg], lb[mlg]; bool check(int a, int b) { if (a < 0 || b < 0 || a > 2 || b > 2) return false; else if ((a & 1) == (b & 1)) return true; else return false; } typedef long long inte; inline int dfs(int p/*第几位*/, bool a/*x 是否进位*/, bool b/*y 是否进位*/, bool lim/*d 是否被顶满*/) { if (p < 0) return (a == 0) && (b == 0); if (vis[p][a][b][lim]) return f[p][a][b][lim]; vis[p][a][b][lim] = true; inte ans = 0; for (int v = 0; v <= (lim ? lb[p] : 2); ++v) { for (int ak = 0; ak <= 1; ++ak) { for (int bk = 0; bk <= 1; ++bk) { if (check(Ab[p] - 3 * a + v + ak, Bb[p] - 3 * b + v + bk)) { ans += dfs(p - 1, ak, bk, lim & (v == lb[p])); } } } } return f[p][a][b][lim] = ans; } signed main() { ios::sync_with_stdio(false); cin.tie(0); int Q; cin >> Q; while (Q--) { inte x, y, d; cin >> d >> x >> y; memset(vis, 0, sizeof(vis)); for (int i = 0; i < mlg; ++i) { Ab[i] = x % 3; x /= 3; Bb[i] = y % 3; y /= 3; lb[i] = d % 3; d /= 3; } cout << dfs(mlg - 1, 0, 0, true) << endl; } return 0; }
- 1
信息
- ID
- 6541
- 时间
- 1000ms
- 内存
- 250MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者