rt。考场上调了几乎 20min。
#include <bits/stdc++.h>
typedef long long ll;
#define int long long
const int N = 2e5 + 10;
struct node { // x 第一关键字,y 第二关键字
int x, y;
bool operator < (const node &cmp) const {
return x != cmp.x ? x < cmp.x : y < cmp.y;
}
} a[N];
int n, m, s, pos[N];
namespace tree {
int tree[N], p[N]; // p 保存位置
int lowbit(int x) { return x & -x; }
void update(int pos, int id, int val) {
for (; pos <= n; pos += lowbit(pos))
if (val > tree[pos]) {
tree[pos] = val;
p[pos] = id;
}
return void();
}
int query(int pos, int &rpos) {
int ans = 0;
for (; pos > 0; pos -= lowbit(pos))
if (tree[pos] > ans) {
ans = tree[pos];
rpos = p[pos];
}
return ans;
}
} ; using namespace tree;
void print(int u) {
if (u == 0) return void();
print(pos[u]);
int x = a[u].x - a[pos[u]].x, y = a[u].y - a[pos[u]].y;
if (! pos[u]) x = a[u].x - 1, y = a[u].y - 1;
while (x --> 0) std::cout << "D";
while (y --> 0) std::cout << "R";
return void();
}
signed main() {
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
std::cin >> n >> m >> s;
for (int i = 1; i <= s; ++ i) std::cin >> a[i].x >> a[i].y;
std::sort(a + 1, a + 1 + s);
// dp[i] 选到第 i 个点的最大路过点数
// dp[i] = max{ dp[j] | x[j] <= x[i], y[j] <= y[i] } + 1
// 发现第一维可以用排序解决,第二维直接树状数组维护即可
// 考虑如何维护转移的位置,直接在树状数组求最大值过程中保存位置即可
int ans = 0, ansid = 0;
for (int i = 1; i <= s; ++ i) {
int tmp = query(a[i].y, pos[i]);
update(a[i].y, i, ++ tmp);
if (tmp > ans) ans = tmp, ansid = i;
}
std::cout << ans << "\n";
pos[++ s] = ansid; a[s].x = n; a[s].y = m;
print(s);
std::cout << "\n";
return 0;
}