• poj3263 Tallest Cow


    题意略去。

    考虑给定的R对pair(A, B)。

    即A能看见B,这意味着B不比A低,并且区间内部的所有元素的高度严格小于A的高度。

    我们规定区间的方向:若A > B,为反方向,反之称为正方向。

    容易发现,区间在同一方向上不交叉,即要么相离,要么相互包含。

    在相反反方向上,若两区间不相互包含,必定是有且仅有一个公共区间端点。

    首先将所有idx上的高度默认设置为H。

    对于相离的区间,他们之间的计算是独立的。

    考虑相互包含的区间,先考虑范围最大的那个区间,处理之间闭区间[A,B]上的高度是相同的,满足此条件只需令(A,B)区间内元素自减一。

    递归考虑其包含的区间,显然这样的做法是最优的且合法的。

    实际上这与考虑区间的次序无关。

    即每得到一个区间,对开区间内的元素减一即可。

    可以用线段树来做区间的修改操作。

    http://poj.org/problem?id=3263

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <set>
     5 using namespace std;
     6 const int maxn = 1e4 + 10;
     7 set< pair<int, int> > S;
     8 struct Seg{
     9     int l, r, h;
    10     int lazy;
    11 }seg[maxn << 2];
    12 int n, m, I, H;
    13 
    14 void build(int u, int l, int r){
    15     seg[u].l = l;
    16     seg[u].r = r;
    17     seg[u].lazy = 0;
    18     seg[u].h = H;
    19     if(r - l < 2) return;
    20     int mid = (l + r) >> 1;
    21     build(u << 1, l, mid);
    22     build(u << 1 | 1, mid, r);
    23 }
    24 
    25 void push_down(int u){
    26     if(seg[u].lazy > 0 && seg[u].r - seg[u].l > 1){
    27         int mid = (seg[u].l + seg[u].r) >> 1;
    28         seg[u << 1].lazy += seg[u].lazy;
    29         seg[u << 1 | 1].lazy += seg[u].lazy;
    30         seg[u << 1].h -= seg[u].lazy;
    31         seg[u << 1 | 1].h -= seg[u].lazy;
    32         seg[u].lazy = 0;
    33     }
    34 }
    35 
    36 void update(int u, int l, int r, int L, int R){
    37     if(R - L < 1) return;
    38     if(L == l && r == R){
    39         seg[u].lazy++;
    40         seg[u].h--;
    41         return;
    42     }
    43     push_down(u);
    44     int mid = (l + r) >> 1;
    45     if(R <= mid) update(u << 1, l, mid, L, R);
    46     else if(L >= mid) update(u << 1 | 1, mid, r, L, R);
    47     else{
    48         update(u << 1, l, mid, L, mid);
    49         update(u << 1 | 1, mid, r, mid, R);
    50     }
    51 }
    52 
    53 void query(int u, int l, int r){
    54     if(r - l == 1){
    55         printf("%d
    ", seg[u].h);
    56         return;
    57     }
    58     push_down(u);
    59     int mid = (l + r) >> 1;
    60     query(u << 1, l, mid);
    61     query(u << 1 | 1, mid, r);
    62 }
    63 
    64 int main(){
    65     while(~scanf("%d%d%d%d", &n, &I, &H, &m)){
    66         build(1, 1, n + 1);
    67         S.clear();
    68         for(int i = 0, u, v; i < m; i++){
    69             scanf("%d%d", &u, &v);
    70             if(u == v || S.find(make_pair(u, v)) != S.end()) continue;
    71             S.insert(make_pair(u, v));
    72             if(u > v) swap(u, v);
    73             update(1, 1, n + 1, u + 1, v);
    74         }
    75         query(1, 1, n + 1);
    76     }
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    gdb 调试器的使用
    vi 的基本操作
    Makefile
    gcc
    动态内存分配
    Linux常用命令
    文件基本操作
    linux的启动配置文件(grub)
    Hello IT
    Val简介(来源维基百科)
  • 原文地址:https://www.cnblogs.com/astoninfer/p/4835989.html
Copyright © 2020-2023  润新知