SDUT 2022 Spring Individual Contest - L(2022江苏省赛) 补题(C、J)
C - Jump and Treasure
题意:
现在总共有从\(0,1,2.....n\),\(n+1\)个柱子,除了\(0\)号柱子,你的最远跳跃距离为\(p\),每个柱子上都有一个宝箱,宝箱的价值为\(a_i\),当你跳到\([n+1,+∞]\)时,游戏胜利,现在有\(Q\)次询问,每次询问给定一个\(x\),每次跳跃只能跳到\(x\)的倍数的柱子上,问你能否游戏胜利,胜利的话,最多能得到多少钱?
思路:
询问\(x\)时,那么可以跳的柱子为\(x,2x,3x....kx\),对于这个序列,进行\(dp\),\(f(i)\)为跳到当前柱子上能得到最多的钱数,那么对于\(dp(kx)\)的值就是\(max(dp((k-1)x,dp(k-2)x....)\),取\(max\)的大小取决于\(p\),然后就是单调队列优化这个\(dp\),如果\(x>p\)一定无法游戏胜利,直接输出不行
View Code
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e6 + 10;
const int inf = 1e18;
#define endl "\n"
int n, q, p;
int a[N];
int dp[N];
int vis[N];
int f[N];
int qmi(int a, int k) {
int res = 1;
while (k) {
if (k & 1) res = res * a;
k >>= 1;
a = a * a;
}
return res;
}
signed main() {
scanf("%lld%lld%lld",&n,&q,&p);
for (int i = 1; i <= n; i++) {
scanf("%lld",&a[i]);
}
int x;
fill(dp, dp + N, -inf);
while (q--) {
scanf("%lld",&x);
if (x > p) {
puts("Noob");
} else {
if (vis[x]) {
printf("%lld\n",dp[x]);
continue;
}
int now = x;
int k = x;
deque<int> q;
q.push_back(0);
for (int i = x; i <= n; i += x) {
while (q.size() && q.front() < i - p) {
q.pop_front();
}
f[i] = f[q.front()] + a[i];
while (q.size() && f[q.back()] < f[i]) {
q.pop_back();
}
q.push_back(i);
if (i + p > n) {
dp[now] = max(dp[now], f[i]);
}
}
vis[now] = 1;
printf("%lld\n",dp[now]);
}
}
}
J - Balanced Tree
题意:
现在定义完美二叉树为对于任何一颗子树来说,左右子树都必须是平衡的,左右子树的结点数量最多差\(1\)。现在给你\(n\)个结点,问你能够构造出多少个完美二叉树
思路:
\(f(x)\)为结点数为\(x\)能够构造出的完美二叉树的数量
\(f(x)=f(\frac{x-1}{2})^2\),\(x\)为奇数,因为此时顶点拿一个结点,现在只剩下偶数个结点,左右两边必须拿相同数量的结点,才能保证平衡
\(f(x)=2f(\frac{x}{2}-1)f(\frac{x}{2})\),\(x\)为偶数,顶点拿一个点,左奇右偶,或左偶右奇,才能保证平衡。
\(g(x)=log_2f(x)\)
那么上面的式子,就变为
\(g(x)=2g(\frac{x-1}{2} )\),\(x\)为奇数
\(g(x)=g(\frac{x}{2} )+g(\frac{x}{2}-1)+1\)
那么\(g(n)=g(n)+0g(n-1)+0\)
把上面的公式套进去进行转换
\(g(0)=0,g(1)=0\)
最终把\(g(n)=ag(1)+bg(0)+c=c\)
所以最终答案就是\(2^c\),若\(c≥64\),取模后就是0
View Code
#include <bits/stdc++.h>
using namespace std;
#define int unsigned long long
#define endl "\n"
int n;
int a, b, c;
void dfs(int x) {
if (x <= 1) return;
if (x & 1) {
c += b;
a = 2 * a + b;
dfs((x - 1) / 2);
} else {
c += a;
b = b * 2 + a;
dfs(x / 2);
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T;
cin >> T;
while (T--) {
cin >> n;
if (n == 1 || n == 0) {
cout << "1" << endl;
continue;
}
a = 1ull, b = 0ull, c = 0ull;
dfs(n);
int now = c;
if (now >= 64) {
cout << "0" << endl;
} else {
int ans = 1ull << now;
cout << ans << endl;
}
}
}

浙公网安备 33010602011771号