vector<int> a(n + 1); for (int i = 1; i <= n; ++i) { a[i] = read(); }
vector pre(M, vector<int>(n + 1, 0)); for (int j = 0; j < M; ++j) { for (int i = 1; i <= n; ++i) { pre[j][i] = pre[j][i - 1] + (a[i] > j); } }
vector<vector<pair<int, int>>> ask(n + 1); vector<int> ans(q + 1); for (int i = 1; i <= q; ++i) { int id = read(), k = read(); if (k > n / 2) { ans[i] = id <= k or a[id] > 1; } // 小小优化 k>n/2 直接出答案 else { ask[k].emplace_back(id, i); } }
for (int k = 1; k <= n / 2; ++k) { if (ask[k].empty()) continue; sort(ask[k].begin(), ask[k].end()); // 注意要排序
// 小范围直接暴力 if (k <= B) { int now = 1, cnt = 0, it = 0; for (int i = 1; i <= n; ++i) { while (it < ask[k].size() and ask[k][it].first == i) { // 注意询问有相同 因此是while ans[ask[k][it].second] = a[i] >= now; ++it; } if (a[i] >= now and ++cnt == k) ++now, cnt = 0; } }
// 大范围二分跳 else { int pos = 0, now = 0, it = 0; while (pos <= n) { pos = lower_bound(pre[now].begin() + pos, pre[now].end(), pre[now][pos] + k) - pre[now].begin(); // 跳到第一个>now有k个的位置 now += 1; while (it < ask[k].size() and ask[k][it].first <= pos) { // 和上面一样的 ans[ask[k][it].second] = a[ask[k][it].first] >= now; ++it; } } } }
for (int i = 1; i <= q; ++i) { printf("%s\n", ans[i] ? "YES" : "NO"); } }
vector<int> a(n + 1); for (int i = 1; i <= n; ++i) { a[i] = read(); }
vector pre(M, vector<int>(n + 1, 0)); for (int i = 1; i <= n; ++i) { for (int j = 0; j < M; ++j) { pre[j][i] = pre[j][i - 1] + (a[i] > j); } } vector<vector<int>> uplevel(n + 1); for (int k = 1; k <= n; ++k) { uplevel[k].push_back(0); if (k <= B) { int now = 0, cnt = 0; for (int i = 1; i <= n; ++i) { if (a[i] > now and ++cnt == k) { uplevel[k].push_back(i); now++; cnt = 0; } } } else { int now = 0, pos = 0; while (pos <= n) { pos = lower_bound(pre[now].begin(), pre[now].end(), k + pre[now][pos]) - pre[now].begin(); uplevel[k].push_back(pos); now++; } } }
for (int i = 0; i < q; ++i) { int id = read(), k = read(); auto ok = a[id] >= uplevel[k].size() or id <= uplevel[k][a[id]]; printf("%s\n", ok ? "YES" : "NO"); } }
BUC2L - 超级 Fibonacci
两个字符串按照Fibonacci 的规则运算,求字符串的指定位。
迁移学习是一种很重要的技能,小F 决心将斐波那契迁移到字符串上。给定两个初始字符串A和B,若之后每个字符串都是前两个字符串拼接而成,那么称这些字符串为斐波那契字符串组,即 F[i]=F[i-1]+F[i-2]。例如,假如 A="a",B="b",那么斐波那契字符串组是:a b ba bab babba babbabab…… 给定 A 和 B,小F 想知道斐波那契字符串组中第x 项的第y 个字符是什么,下标从 1 开始。
vector<vector<int>> c(10); c[2].push_back(1); c[3].push_back(2); c[4].push_back(3); for (int ti = 0; ti < 12; ti++) { int a, b; cin >> a >> b; bool flag = 0; for (int i = 1; i <= 9; i++) { for (int j = 0; j < c[i].size(); j++) { if (c[i][j] == a) { for (int k = j; k < c[i].size(); k++) { c[i + b].push_back(c[i][k]); } for (int k = c[i].size() - 1; k >= j; k--) { c[i].erase(c[i].begin() + k); } flag = 1; break; } } if (flag) break; } } cout << (c[9].size() == 3 ? "Y" : "N") << "\n";