CodeForces - 1632D New Year Concert(ST 表、二分)
题目大意:
给出一个序列 。
对于一个序列 ,如果其中存在一个区间 ,满足区间 等于区间长度 ,则认为这个序列是不好的。
每次修改可以将任意一个数改成任意正整数。
现求对序列 的每一个前缀最少需要修改多少次,使得该前缀是一个好序列。
思路:
通过简单模拟一下样例 ,我们可以发现。
- 的状态继承了 的状态。并且假设每次答案最多增加 (但还是不太懂为什么)
- 对于一个区间 ,其区间 满足单调递增。
- 为了让修改次数最少,我们可以每次将数修改为一个大质数,因为区间 单调递增,那么修改成大质数的话,我们就不用考虑这个质数所在位置及其前面的数字了,他们与区间右端点的 都为 ,而要想满足是不好序列的条件只用检查区间端点。
由于我们并不需要真的去修改一个数,我们可以用 ST 表预处理出区间 。
那么,现在问题就在于当我们考虑以 位置为结尾的前缀时,我们如何求出 这段区间上我们要修改几次。
前面说到 的状态可以由 的状态转移得到,并且我们在 之前可能会进行一些修改操作,将某些数字改成大质数,那么我们可以用变量 记录上一次修改的位置,问题就由转化成如何求出在 这段区间上我们要修改几次。
由单调性考虑二分,二分找是否存在一个位置 ,使得 是一个不合法区间。
令 为区间 的 , 为 的区间长度。
因为 单调递增, 单调递减,那么一定会出现以下的局面。
----------------|*|------------------*>
tmp < len tmp > len i
不合法
这样我们就能二分的找是否存在这个位置 。
Code:
class SparseTable {
public:
int lg[N] = {-1};
ll st[24][N];
template <class T>
T op(T &a, T &b) { return gcd(a, b); } //检查区间操作!
SparseTable() {
for (int i = 1; i < N; i++) {
lg[i] = lg[i / 2] + 1;
}
}
inline void init(int n, vector<ll> &a) {
//完成初始化! for i in [1, n]: st[0][i] = val[i], 对应区间 [i, i + 2^0 -1]
for (int i = 1, x; i <= n; i++) {
st[0][i] = a[i];
}
build(n);
}
inline void build(int n) {
for (int i = 1; i <= lg[n]; i++)
for (int j = 1; j + (1 << i) - 1 <= n; j++)
st[i][j] = op(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
}
ll query(int l, int r) {
ll len = lg[r - l + 1];
return op(st[len][l], st[len][r - (1 << len) + 1]);
}
};
SparseTable ST;
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n;
cin >> n;
vector<ll> a(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
ST.init(n, a);
ll ans = 0;
int idx = 1; // 将a[idx - 1]修改为大质数
for (int i = 1; i <= n; i++) {
if (a[i] == 1) {
ans++;
idx = i + 1;
} else {
int l = idx, r = i; // 二分找是否存在一个位置p,使得[p, i]是一个bored区间
bool cur = false;
while (l <= r) {
int mid = (l + r) >> 1;
int tmp = ST.query(mid, i);
int len = i - mid + 1;
if (tmp < len) {
l = mid + 1;
} else if (tmp == len) {
cur = true;
break;
} else {
r = mid - 1;
}
}
if (cur) {
ans++;
idx = i + 1;
}
}
cout << ans << " \n"[i == n];
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】