题意是数轴上有n个商店,分别在1~n,起点是0,要走到n+1,必须每个商店都进去一次.有的商店进入有先后关系,比如要先进第i个商店才能进第j个商店(i>j).求走的最少步数.
既然关系都是逆的,对于每个关系看成一个区间,最终的答案就是n+1+所有区间长度并*2.
然后没看数据量直接上了棵线段树~
#include <bits/stdc++.h>
using namespace std;
#define maxn 1111
#define pl c<<1
#define pr (c<<1)|1
#define lson tree[c].l,tree[c].mid,c<<1
#define rson tree[c].mid+1,tree[c].r,(c<<1)|1
struct node {
int l, r, mid;
int sum;
bool full;
}tree[maxn<<4];
int n, m;
void build_tree (int l, int r, int c) {
tree[c].l = l, tree[c].r = r, tree[c].mid = (l+r)>>1;
tree[c].full = 0;
tree[c].sum = 0;
if (l == r)
return ;
build_tree (lson);
build_tree (rson);
return ;
}
void push_down (int c) {
if (tree[c].l == tree[c].r)
return ;
if (tree[c].full == 1) {
tree[pl].full = tree[pr].full = 1;
tree[pl].sum = tree[pl].r-tree[pl].l+1;
tree[pr].sum = tree[pr].r-tree[pr].l+1;
}
return ;
}
void update (int l, int r, int c, int x, int y) {
push_down (c);
if (l == x && y == r) {
tree[c].full = 1;
tree[c].sum = r-l+1;
return ;
}
if (tree[c].mid >= y) {
update (lson, x, y);
}
else if (tree[c].mid < x) {
update (rson, x, y);
}
else {
update (lson, x, tree[c].mid);
update (rson, tree[c].mid+1, y);
}
tree[c].sum = tree[pl].sum + tree[pr].sum;
}
int main () {
//freopen ("in", "r", stdin);
while (scanf ("%d%d", &n, &m) == 2) {
build_tree (1, n, 1);
for (int i = 1; i <= m; i++) {
int l, r;
scanf ("%d%d", &l, &r);
if (l >= r)
continue;
update (1, n, 1, l+1, r);
}
printf ("%d\n", n+1+tree[1].sum*2);
}
return 0;
}