牛客周赛 Round 120 题解
https://anoth3r.top/solution/nkwk120/
A 无穷无尽的力量
直接输出即可。
void solve() {
int n;
cin >> n;
cout << string(n, 'a') << 'b' << string(n, 'a') << "\n";
}
B 无穷无尽的字符串
显然有 个周期,剩下的字母我们可以通过检查
和
的关系确定是否检查到刚刚已经计算过的区间。
void solve() {
int l, r;
cin >> l >> r;
l--;
int a, b, c;
a = b = c = (r - l) / 3;
while (r % 3 != l % 3) {
a += r % 3 == 1;
b += r % 3 == 2;
c += r % 3 == 0;
r--;
}
cout << a << " " << b << " " << c << "\n";
}
C 无穷无尽的力量2.0
记 为短边,
为长边,马的移动为
或
。
当 时,显然跳不了,答案为
。
当 时,显然只能上下跳,答案为
。
当 且
时,除了中间的点其他都可以任意跳。
剩余情况,每一个点都是可达的。
注意 超
范围。
void solve() {
ll n, m;
cin >> n >> m;
if (n > m) swap(n, m);
if (n == 1) cout << 1 << "\n";
else if (n == 2) cout << (m - 1) / 2 + 1 << "\n";
else if (n == 3 && m == 3) cout << 8 << "\n";
else cout << n*m << "\n";
}
D 无穷无尽的小数
,并且
,不觉得这是一件非常诡异的事情嘛。
显然肯定有长度为 的循环节,把两个数扩展到
的长度,在
前加个
,
前加个
,直接做高精度减法即可。
注意初始的 为
,因为需要考虑下一个循环有没有借
。
void solve() {
int n, m;
cin >> n >> m;
string a, b;
cin >> a >> b;
string A = "", B = "";
for (int i = 0; i < 2 * m; ++i) A += a;
for (int i = 0; i < 2 * n; ++i) B += b;
A += '9';
B += '0';
int brw = a[0] < b[0];
string ans = "";
for (int i = n * m - 1; i >= 0; --i) {
A[i] -= brw;
brw = 0;
if (A[i] < B[i]) brw = 1;
int val = brw * 10 + A[i] - B[i];
ans += (char)(val + '0');
}
reverse(all(ans));
cout << n*m << "\n";
for (int i = 0; i < n * m; ++i) cout << ans[i];
cout << "\n";
}
E 无穷无尽的树
叶子节点:
- 如果
是原树的叶子,它对答案没有贡献。
- 返回一个无效状态,例如
。
- 当前节点的答案输出
。
非叶子节点:
-
本身不是叶子,所以
会留在树中。初始状态设为
。
-
遍历所有子节点
,获取
返回的
。
状态转移:
-
如果子树返回的深度
当前记录的
:更新
。
-
如果子树返回的深度
当前记录的
:累加
。
-
如果子树返回的深度
:忽略。
-
记录当前节点的答案为
。
-
将合并后的
返回给父节点。
void solve() {
int n;
cin >> n;
vector<vector<int>> adj(n + 1);
vector<int> dep(n + 1), ans(n + 1);
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
adj[u].pb(v);
adj[v].pb(u);
}
function<PII(int, int, int)> dfs = [&](int u, int p, int d) {
dep[u] = d;
bool f = true;
int mx = d;
int cnt = 1;
for (int v : adj[u]) {
if (v == p) continue;
f = false;
PII res = dfs(v, u, d + 1);
if (res.fi == -1) continue;
if (res.fi > mx) {
mx = res.fi;
cnt = res.se;
} else if (res.fi == mx) {
cnt += res.se;
}
}
if (f) {
ans[u] = 0;
return make_pair(-1, 0);
} else {
ans[u] = cnt;
return make_pair(mx, cnt);
}
};
if (n == 1) {
cout << "0" << "\n";
return;
}
dfs(1, 0, 1);
for (int i = 1; i <= n; ++i) {
cout << ans[i] << " ";
}
cout << "\n";
}
F 无穷无尽的数
这个区间 在结构上由三部分组成:
- 头部:
的某个后缀(从下标
开始到
)。
- 中间:
个完整的
。
- 尾部:
的某个前缀(从
开始到
)。
我们可以预处理前缀,令 表示
的数值,则子串
的数值可以通过
得到。
对于中间部分,实际上是一个等比数列,公比是 。
最终答案为
void solve() {
ll n, l, r;
cin >> n >> l >> r;
string s;
cin >> s;
vector<Z> p(n + 1), h(n + 1);
p[0] = 1;
for (int i = 0; i < n; ++i) {
p[i + 1] = p[i] * 10;
h[i + 1] = h[i] * 10 + (s[i] - '0');
}
auto g = [&](int i, int j) {
return h[j + 1] - h[i] * p[j - i + 1];
};
ll u = (l - 1) / n, v = (r - 1) / n;
int x = (l - 1) % n, y = (r - 1) % n;
if (u == v) {
cout << g(x, y) << "\n";
return;
}
ll k = v - u - 1;
Z mid = 0;
if (k > 0) {
mid = h[n] * (ksm(Z(10), n * k) - 1) / (ksm(Z(10), n) - 1);
}
cout << g(x, n - 1)*ksm(Z(10), n * k + y + 1) + mid*ksm(Z(10), y + 1) + g(0, y) << "\n";
}
头文件
//Another
#include<bits/stdc++.h>
#include<bits/extc++.h>
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef __int128 i128;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef tuple<ll, ll, ll> TLLL;
typedef __gnu_pbds::tree<PLL, __gnu_pbds::null_type, less<PLL>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update> Tree;
// typedef __gnu_pbds::tree<ll, __gnu_pbds::null_type, less<ll>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update> Tree;
constexpr int inf = (ll)1e9 + 7;
constexpr ll INF = (ll)2e18 + 9;
// constexpr ll INF = (ll)4e18;
// constexpr ll MOD = 1e9 + 7;
constexpr ll MOD = 998244353;
constexpr ld PI = acos(-1.0);
constexpr ld eps = 1e-10;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ull randint(ull l, ull r) {uniform_int_distribution<unsigned long long> dist(l, r); return dist(rng);}
void init() {
}
void solve() {
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
init();
int t = 1;
// cin >> t;
for (int _ = 1; _ <= t; ++_) {
solve();
}
return 0;
}
自动取模
template<class T>
constexpr T ksm(T a, ll b) {
T res = 1;
while (b) {
if (b & 1) res *= a;
b >>= 1;
a *= a;
}
return res;
}
template<int P>
struct MInt {
int x;
constexpr MInt(): x() {}
constexpr MInt(ll x) : x{norm(x % getMod())} {}
static int Mod;
constexpr static int getMod() {
if (P > 0) {
return P;
} else {
return Mod;
}
}
constexpr static void setMod(int Mod_) {
Mod = Mod_;
}
constexpr int norm(int x) const {
if (x < 0) {
x += getMod();
}
if (x >= getMod()) {
x -= getMod();
}
return x;
}
constexpr int val() const {
return x;
}
explicit constexpr operator int() const {
return x;
}
constexpr MInt operator-() const {
MInt res;
res.x = norm(getMod() - x);
return res;
}
constexpr MInt inv() const {
assert(x != 0);
return ksm(*this, getMod() - 2);
}
constexpr MInt &operator*=(MInt rhs) & {
x = 1LL * x * rhs.x % getMod();
return *this;
}
constexpr MInt &operator+=(MInt rhs) & {
x = norm(x + rhs.x);
return *this;
}
constexpr MInt &operator-=(MInt rhs) & {
x = norm(x - rhs.x);
return *this;
}
constexpr MInt &operator/=(MInt rhs) & {
return *this *= rhs.inv();
}
friend constexpr MInt operator*(MInt lhs, MInt rhs) {
MInt res = lhs;
res *= rhs;
return res;
}
friend constexpr MInt operator+(MInt lhs, MInt rhs) {
MInt res = lhs;
res += rhs;
return res;
}
friend constexpr MInt operator-(MInt lhs, MInt rhs) {
MInt res = lhs;
res -= rhs;
return res;
}
friend constexpr MInt operator/(MInt lhs, MInt rhs) {
MInt res = lhs;
res /= rhs;
return res;
}
friend constexpr istream &operator>>(istream &is, MInt &a) {
ll v;
is >> v;
a = MInt(v);
return is;
}
friend constexpr ostream &operator<<(ostream &os, const MInt &a) {
return os << a.val();
}
friend constexpr bool operator==(MInt lhs, MInt rhs) {
return lhs.val() == rhs.val();
}
friend constexpr bool operator!=(MInt lhs, MInt rhs) {
return lhs.val() != rhs.val();
}
};
template<>
int MInt<0>::Mod = 998244353;
using Z = MInt<MOD>;

京公网安备 11010502036488号