poj 1769 Minimizing maximizer 线段树

来源:互联网 发布:造梦西游4修改器mac版 编辑:程序博客网 时间:2024/06/10 00:42

题目

题目链接:http://poj.org/problem?id=1769

题目来源:《挑战》例题。

简要题意:排序器将某区间的排序其他不变,排序器序列最后一个输出的最后一个就是最终结果,问至少要多少排序器最终一定能得到最大值。

题解

整个东西就是线段树的单点更新,区间求和。

维护一个线段树,保存和询问区间的最小值。

对于当前的区间,区间内的最小值+1就是最大值移到右端点的最少次数。

将最少次数更新到线段树中,循环往复。

由于要考虑最坏的情况,因而令1的位置为0,然后最后就是去query n的位置。

代码

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>#include <stack>#include <queue>#include <string>#include <vector>#include <set>#include <map>#define fi first#define se secondusing namespace std;typedef long long LL;typedef pair<int,int> PII;// headconst int N = 5e4+5;const int INF = 0x3f3f3f3f;struct SegmentTree {    #define lson (rt<<1)    #define rson ((rt<<1)|1)    #define MID ((L+R)>>1)    #define lsonPara lson, L, MID    #define rsonPara rson, MID+1, R    const static int TN = N << 2;    int t[TN];    void pushUp(int rt) {        t[rt] = min(t[lson], t[rson]);    }    void build(int rt, int L, int R) {        if (L == R) {            t[rt] = INF;        } else {            build(lsonPara);            build(rsonPara);            pushUp(rt);        }    }    void modify(int rt, int L, int R, int x, int v) {        if (x < L || x > R) return;        if (L == R) {            t[rt] = min(t[rt], v);        } else {            modify(lsonPara, x, v);            modify(rsonPara, x, v);            pushUp(rt);        }    }    int query(int rt, int L, int R, int l, int r) {        if (l > R || r < L || l > r) return INF;        if (l <= L && r >= R) return t[rt];        return min(query(lsonPara, l, r), query(rsonPara, l, r));    }};SegmentTree st;int main() {    int n, m, l, r;    while (scanf("%d%d", &n, &m) == 2) {        st.build(1, 1, n);        st.modify(1, 1, n, 1, 0);        for (int i = 0; i < m; i++) {            scanf("%d%d", &l, &r);            int ans = st.query(1, 1, n, l, r);            st.modify(1, 1, n, r, ans + 1);        }        printf("%d\n", st.query(1, 1, n, n, n));    }    return 0;}
0 0
原创粉丝点击