zoukankan      html  css  js  c++  java
  • Codeforces

    题意:

      给出n行,109列的01矩阵,矩阵中的1是由m段连续的横向区间构成。问至少删除多少行,使得剩下的任意两行之间至少有同一列都为1;并输出删除方案。

    题解:

      假定某两行有同一列是1,那么称这两行相连。

      即使有109列,但是成段的1也只有m段而已。

      总体是dp的思想:从上往下扫每一行,当前行的答案是它上面和它相连的行的答案的最大值+1

      用线段树优化dp,维护每个区间的答案最大值以及最大值时的行号。

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 3e5+10;
    typedef pair<int, int> P;
    int n, m, tot;
    int p, l, r;
    int last[N];
    int visit[N];
    vector<int> v;
    vector<P> g[N];
    P lzy[N<<4], tree[N<<4];
    
    int get_pos(int x) {
        return lower_bound(v.begin(), v.end(), x) - v.begin() + 1;
    }
    
    void push_up(int id) {
        P val = max(tree[id<<1], tree[id<<1|1]);
        tree[id] = max(tree[id], val);
    }
    
    void push_down(int id) {
        if(lzy[id].first == 0)
            return;
        lzy[id<<1] = max(lzy[id<<1], lzy[id]);
        lzy[id<<1|1] = max(lzy[id<<1|1], lzy[id]);
        tree[id<<1] = max(tree[id<<1], lzy[id]);
        tree[id<<1|1] = max(tree[id<<1|1], lzy[id]);
        lzy[id] = make_pair(0, 0);
    }
    
    void insert(int id, int l, int r, int ql, int qr, P val) {
        if(ql <= l && r <= qr) {
            tree[id] = max(tree[id], val);
            lzy[id] = max(lzy[id], val);
            return;
        }
        push_down(id);
        int mid = (l + r) >> 1;
        if(ql <= mid) insert(id<<1, l, mid, ql, qr, val);
        if(qr > mid) insert(id<<1|1, mid+1, r, ql, qr, val);
        push_up(id);
    }
    
    P query(int id, int l, int r, int ql, int qr) {
        if(ql <= l && r <= qr) {
            return tree[id];
        }
        push_down(id);
        int mid = (l + r) >> 1;
        P now = make_pair(0, 0);
        if(ql <= mid) now = query(id<<1, l, mid, ql, qr);
        if(qr > mid) now = max(now, query(id<<1|1, mid+1, r, ql, qr));
        push_up(id);
        return now;
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        while(m--) {
            scanf("%d%d%d", &p, &l, &r);
            g[p].push_back(make_pair(l, r));
            v.push_back(l);
            v.push_back(r);
        }
    
        sort(v.begin(), v.end());
        v.erase(unique(v.begin(), v.end()), v.end());
        tot = v.size();
    
        P ans = make_pair(0, 0);
        for(int i = 1; i <= n; i++) {
            P res = make_pair(0, 0);
            for(int j = 0; j < g[i].size(); j++) {
                l = get_pos(g[i][j].first);
                r = get_pos(g[i][j].second);
                res = max(res, query(1, 1, tot, l, r));
            }
    
            last[i] = res.second;
            res.first++;
            res.second = i;
            ans = max(ans, res);
    
            for(int j = 0; j < g[i].size(); j++) {
                l = get_pos(g[i][j].first);
                r = get_pos(g[i][j].second);
                insert(1, 1, tot, l, r, res);
            }
        }
    
        int pos = ans.second;
        while(pos) {
            visit[pos] = 1;
            pos = last[pos];
        }
        printf("%d
    ", n - ans.first);
        bool flag = false;
        for(int i = 1; i <= n; i++) {
            if(!visit[i]) {
                if(flag)
                    printf(" ");
                flag = true;
                printf("%d", i);
            }
        }
    }
    C++
    package main
    import (
        "io"
        "os"
        "fmt"
        "sort"
        "bufio"
    )
    const N int = 3e5+10
    var n, m, tot int
    var p, l, r int
    var last, visit [N]int
    var v sort.IntSlice
    var g [][]pair
    var lzy, tree [N<<4]pair
    type pair struct {
        first, second int
    }
    
    func max(x, y pair) pair {
        if x.first > y.first {
            return x
        }
        if x.first == y.first {
            if x.second > y.second {
                return x
            }
        }
        return y
    }
    
    func get_pos(x int) int {
        l := 0
        r := tot - 1
        for l <= r {
            mid := (l + r) >> 1
            if v[mid] < x {
                l = mid + 1
            } else {
                r = mid - 1
            }
        }
        return l + 1
    }
    
    func push_up(id int) {
        val := max(tree[id<<1], tree[id<<1|1])
        tree[id] = max(tree[id], val)
    }
    
    func push_down(id int) {
        if lzy[id].first == 0 {
            return
        }
        lzy[id<<1] = max(lzy[id<<1], lzy[id])
        lzy[id<<1|1] = max(lzy[id<<1|1], lzy[id])
        tree[id<<1] = max(tree[id<<1], lzy[id])
        tree[id<<1|1] = max(tree[id<<1|1], lzy[id])
        lzy[id] = pair{0, 0}
    }
    
    func insert(id, l, r, ql, qr int, val pair) {
        if ql <= l && r <= qr {
            tree[id] = max(tree[id], val)
            lzy[id] = max(lzy[id], val)
            return
        }
        push_down(id)
        mid := (l + r) >> 1
        if ql <= mid {
            insert(id<<1, l, mid, ql, qr, val)
        }
        if qr > mid {
            insert(id<<1|1, mid+1, r, ql, qr, val)
        }
        push_up(id)
    }
    
    func query(id, l, r, ql, qr int) pair {
        if ql <= l && r <= qr {
            return tree[id]
        }
        push_down(id)
        mid := (l + r) >> 1
        now := pair{0, 0}
        if ql <= mid {
            now = query(id<<1, l, mid, ql, qr)
        }
        if qr > mid {
            now = max(now, query(id<<1|1, mid+1, r, ql, qr))
        }
        push_up(id)
        return now
    }
    
    func main() {
        var input io.Reader = bufio.NewReader(os.Stdin)
        
        fmt.Fscan(input, &n)
        for i := 1; i <= n + 1; i++ {
            tmp := []pair{}
            g = append(g, tmp)
        }
    
        for fmt.Fscan(input, &m); m > 0; m-- {
            fmt.Fscan(input, &p)
            fmt.Fscan(input, &l)
            fmt.Fscan(input, &r)
            g[p] = append(g[p], pair{l, r})
            v = append(v, l, r)
        }
    
        sort.Ints(v)
        l = 0
        for i, _ := range v {
            if i == 0 || v[i] != v[i-1] {
                v[l] = v[i]
                l++
            }
        }
        v = v[0:l]
        tot = len(v)
    
        ans := pair{0, 0}
        for i := 1; i <= n; i++ {
            res := pair{0, 0}
            for _, val := range g[i] {
                l = get_pos(val.first)
                r = get_pos(val.second)
                res = max(res, query(1, 1, tot, l, r))
            }
    
            last[i] = res.second
            res.first++
            res.second = i
            ans = max(ans, res)
    
            for _, val := range g[i] {
                l = get_pos(val.first)
                r = get_pos(val.second)
                insert(1, 1, tot, l, r, res)
            }
        }
    
        pos := ans.second
        for pos > 0 {
            visit[pos] = 1
            pos = last[pos]
        }
        fmt.Println(n - ans.first)
        flag := false
        for i := 1; i <= n; i++ {
            if visit[i] == 0 {
                if flag {
                    fmt.Print(" ")
                }
                flag = true
                fmt.Print(i)
            }
        }
    }
    Go
  • 相关阅读:
    HYSBZ 3813 奇数国
    HYSBZ 4419 发微博
    HYSBZ 1079 着色方案
    HYSBZ 3506 排序机械臂
    HYSBZ 3224 Tyvj 1728 普通平衡树
    Unity 3D,地形属性
    nginx 的naginx 种包含include关键字
    Redis 出现NOAUTH Authentication required解决方案
    mysql 8.0出现 Public Key Retrieval is not allowed
    修改jar包里的源码时候需要注意的问题
  • 原文地址:https://www.cnblogs.com/Pneuis/p/15164226.html
Copyright © 2011-2022 走看看