AGC056C 题解
直接做不好做,考虑将条件转化。令
容易发现,想要最小化原串的字典序,其实就是让
我们发现,给定的条件
同时根据定义可得
列出我们已知的条件:
-
\forall \ 1\le i \le m, \ d_{l_i - 1} = d_{r_i} -
\forall \ 1< i \le n,\ |d_i - d_{i-1}| \le 1
条件的特殊性启发我们采用差分约束系统求解本题,同时差分约束系统也可以很好地满足使
对
由于边权的特殊性,我们可以通过 01bfs 求解所有
总时间复杂度
#include <bits/stdc++.h>
using namespace std;
template <typename T> void get(T & x) {
x = 0; char ch = getchar(); bool f = false; while (ch < '0' or ch > '9') f = f or ch == '-', ch = getchar();
while ('0' <= ch and ch <= '9') x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); f && (x = -x);
} template <typename T, typename ... Args> void get(T & a, Args & ... b) { get(a); get(b...); }
#define rep(i,s,t) for (register int i = (s), i##_ = (t) + 1; i < i##_; ++ i)
#define pre(i,s,t) for (register int i = (s), i##_ = (t) - 1; i > i##_; -- i)
const int N = 1e6 + 10;
int n, m, l, r;
vector <pair<int,int> > g[N];
int dis[N];
deque<int> que;
void bfs(int st) {
memset(dis, -1, sizeof dis);
dis[st] = 0; que.push_back(st);
while (que.size()) {
int u = que.front(); que.pop_front();
for (auto [v, w] : g[u]) {
if (dis[v] == -1) {
dis[v] = dis[u] + w;
if (w == 0) que.push_front(v);
else que.push_back(v);
}
}
}
}
int main() {
get(n, m);
rep(i,1,m) get(l, r), g[r].emplace_back(l - 1, 0), g[l - 1].emplace_back(r, 0);
rep(i,1,n) g[i - 1].emplace_back(i, 1), g[i].emplace_back(i - 1, 1);
bfs(0);
rep(i,1,n) cout << (dis[i] < dis[i - 1]);
}