P16434 [APIO 2026 中国赛区] 蛋糕 题解
So_noSlack · · 题解
这题出的还是挺好的,思维链引导比较完整,和 perm 有异曲同工之妙。
对于 sub1,直接构造
对于 sub2,目的是找到一种构造,使得一次询问的三个结果对应三种可能值,总共就没几种情况,手玩一下就找到了
前两个 sub 没什么好说的,大概就花费了
对于 sub3,这个就需要思考一下了,因为
然后考虑怎么询问能把
知道了
有一些边界需要注意,除了边界情况,这样询问次数是严格
::::info[一个很可能陷入的误区]
这里需要说一下,我做的时候把找
这和 perm 可能遇到的问题很像,如果做 perm 的时候陷入二分的解法很可能就无法想到正解。 ::::
对于 sub4,其实 sub3 的做法稍微优化一下就能拿到这部分的
可以发现
另外
对于给定的
令
- 若返回
-1 ,说明d 在[l+2k,l+3k] 范围内,令l \gets l+2k,k \gets \frac{k}{3} 。 - 若返回
0 ,说明d 在[l+k,l+2k] 范围内,令l \gets l+k,k \gets \frac{k}{3} 。 - 若返回
1 ,说明d 在[l,l+k] 范围内,令k \gets \frac{k}{3} 。
具体原因就不写了,比较显然。初始时令
#include<bits/stdc++.h>
#include"cake.h"
using namespace std;
#define ll long long
int p[10];
vector<int> bake_cakes(int N, int W, int K) {
vector<int> v; v.clear();
if(N == 3000 && W == 100) for(int i = 1; i <= W; i ++) v.push_back(i);
if(N == 3) v.push_back(1), v.push_back(3);
if(N == 40) {
v.push_back(1);
for(int i = 0; i <= 29; i ++) if((1 << i) <= W) v.push_back(1 << i);
}
if(N == 3000 && W == 2000) {
p[0] = 1;
for(int i = 1; i <= 7; i ++) p[i] = p[i - 1] * 3;
for(int i = 1; i <= 2188; i ++) v.push_back(i);
}
return v;
}
ll check(ll x) {
vector<int> s1, s2; s1.clear(), s2.clear();
s2.push_back(x + 1);
for(int i = 0; i <= x; i ++) s1.push_back(i);
return compare_tastiness(s1, s2);
}
int find_tastiness(int m, int W, int K) {
if(K == 100) for(int i = 1; i <= W; i ++) {
vector<int> s1, s2; s1.clear(), s2.clear();
s1.push_back(i - 1), s2.push_back(i);
if(compare_tastiness(s1, s2) == 0) return i;
}
if(K == 1) {
vector<int> s1, s2; s1.clear(), s2.clear();
s1.push_back(0), s1.push_back(1), s2.push_back(2);
ll x = compare_tastiness(s1, s2);
if(x == -1) return 1;
if(x == 0) return 2;
if(x == 1) return 3;
}
if(K == 30) {
ll res = 0;
vector<int> s1, s2; s1.clear(), s2.clear();
for(int i = 0; i < m - 1; i ++) s1.push_back(i);
s2.push_back(m - 1);
for(int i = m - 2; i >= 0; i --) {
ll x = compare_tastiness(s1, s2);
if(x == 0) {
s1.clear(), s1.push_back(i + 1);
s2.clear(), s2.push_back(i + 2);
for(int j = i; j >= 1; j --) {
s1.push_back(j), x = compare_tastiness(s1, s2);
if(x == 1) s1.pop_back();
else if(x == 0) break;
}
for(auto it : s1) res += (it > 0 ? (1 << it - 1) : 1);
break;
}
s1.pop_back(), s2.pop_back(), s2.push_back(i);
}
return res;
}
if(K == 7) {
int l = 0;
for(int i = 6; i >= 0; i --) {
ll x = compare_tastiness({l, l + 3 * p[i]}, {l + p[i], l + 2 * p[i]});
if(x == -1) l += 2 * p[i];
else if(x == 0) l += p[i];
}
return l + 1;
}
}
/*
40 1000000000 30 7
1000000000 1 2 3 999999999 536870913 805306367
*/