Description
有一个长度为 nnn 的序列 A=(A1,A2,⋯ ,An)A=(A_1,A_2,\cdots,A_n)A=(A1,A2,⋯,An)。
有 mmm 次操作,每个操作格式如下:
1 x v:将 AxA_xAx 修改成 vvv。2 x:将序列 AAA 冒泡排序,求出原先的 AxA_xAx 排序后的位置,然后将 AAA 复原。
Analysis
修改次数不多,考虑从这入手。
先对 AAA 排序,并记录 tit_iti 表示原先的 AiA_iAi 排序后的位置。
接下来可以发现,修改有序序列中的一个数后,可以通过前后冒泡各一次来保持有序。(因为不知道改小了还是改大了)
排完后,重新记录一遍 tit_iti 即可。
另外,由于 AAA 已经排过序,所以实现时需要改 AtxA_{t_x}Atx 而不是 AxA_xAx。
关键代码:
// Read data from standard input.
vector<PII> a(n);
for(int i = 0; i < n; i++){
cin >> a[i].first;
a[i].second = i;
}
sort(a.begin(), a.end());
// a[i].first: The value of this element。
// a[i].second: After sorting, the position of a[i] in the original sequence.
// t[i] represents the position of a[i] before sorting in the sorted sequence `a`.
vector<int> t(n);
for(int i = 0; i < n; i++) t[a[i].second] = i;
// Modify
auto update = [&](int x, int v){
// Note that the sequence here has already been sorted,
// so it needs to be changed to a[t[x]] instead of a[x].
a[t[x]].first = v;
// Scan from back to front (becoming less).
for(int j = n - 1; j >= 1; j--)
if(a[j] < a[j - 1]) swap(a[j], a[j - 1]);
// Scan from front to back (becoming greater).
for(int j = 1; j < n; j++)
if(a[j] < a[j - 1]) swap(a[j], a[j - 1]);
for(int i = 0; i < n; i++) t[a[i].second] = i;
};
查询的话,从定义出发,易得答案就是 tit_iti。
Code
注:代码中,下标从 000 开始。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define int long long
typedef pair<int, int> PII;
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
vector<PII> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i].first;
a[i].second = i;
}
sort(a.begin(), a.end());
vector<int> t(n);
for (int i = 0; i < n; i++) t[a[i].second] = i;
auto update = [&](int x, int v) {
a[t[x]].first = v;
for (int j = n - 1; j >= 1; j--)
if (a[j] < a[j - 1]) swap(a[j], a[j - 1]);
for (int j = 1; j < n; j++)
if (a[j] < a[j - 1]) swap(a[j], a[j - 1]);
for (int i = 0; i < n; i++) t[a[i].second] = i;
};
for (int i = 0, op, x, v; i < m; i++) {
cin >> op >> x;
x--;
if (op == 1) {
cin >> v;
update(x, v);
} else cout << t[x] + 1 << endl;
}
return 0;
}
1119

被折叠的 条评论
为什么被折叠?



