zoukankan      html  css  js  c++  java
  • POJ 2482 Stars in Your Window 线段树

      如果按一般的思路来想,去求窗户能框住的星星,就很难想出来。

      如果换一个思路,找出每颗星星能被哪些窗户框住,这题就变得非常简单了。

      不妨以每个窗户的中心代表每个窗户,那么每颗星星所对应的窗户的范围即以其为中心的、W*H的矩形。把这些矩形的左边和右边,分别加上和减去其价值。而统计这些边只需要开一个线段树统计即可,用每次加边后得到的最大值更新答案。

      需要注意的是,计算这些边上两点的坐标时可能出现0.5的情况,为了避免,把原坐标*2即可。而且坐标过大,需要离散化。

      一开始打的时候,竟然,错了样例。仔细看了之后才发现窗户的长度为框住的点数+1,TAT

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <string>
      5 #include <algorithm>
      6 #include <iostream>
      7 #include <map>
      8 
      9 using namespace std;
     10 
     11 #define ls (rt<<1)
     12 #define rs ((rt<<1)+1)
     13 typedef long long LL;
     14 const int maxn = 20005;
     15 int n, m, W, H;
     16 struct Node
     17 {
     18     LL x, y1, y2, v;
     19     Node (LL x = 0, LL y1 = 0, LL y2 = 0, int v = 0):
     20         x(x), y1(y1), y2(y2), v(v) {}
     21     bool operator < (const Node &AI) const
     22     {
     23         if (x == AI.x)
     24             return v < AI.v;
     25         return x < AI.x;
     26     }
     27 }line[maxn*2];
     28 LL t[maxn];
     29 struct Tree
     30 {
     31     LL mv[maxn*4], delta[maxn*4];
     32     void Build(int rt, int l, int r)
     33     {
     34         delta[rt] = mv[rt] = 0;
     35         if (l == r)
     36             return ;
     37         int mid = (l+r)>>1;
     38         Build(ls, l, mid);
     39         Build(rs, mid+1, r);
     40     }
     41     void PushUp(int rt)
     42     {
     43         mv[rt] = max(mv[ls], mv[rs]);
     44     }
     45     void PushDown(int rt)
     46     {
     47         mv[ls] += delta[rt], mv[rs] += delta[rt];
     48         delta[ls] += delta[rt], delta[rs] += delta[rt];
     49         delta[rt] = 0;
     50     }
     51     void Update(int rt, int l, int r, int L, int R, int k)
     52     {
     53         if (L <= l && r <= R)
     54         {
     55             mv[rt] += k;
     56             delta[rt] += k;
     57             return ;
     58         }
     59         if (delta[rt] != 0)
     60             PushDown(rt);
     61         int mid = (l+r)>>1;
     62         if (L <= mid)
     63             Update(ls, l, mid, L, R, k);
     64         if (R > mid)
     65             Update(rs, mid+1, r, L, R, k);
     66         PushUp(rt);
     67     }
     68 }T;
     69 map <LL, int> num_y;
     70 
     71 int main()
     72 {
     73     while (~scanf("%d %d %d", &n, &W, &H))
     74     {
     75         W ++, H ++;
     76         m = 0;
     77         int Tcnt = 0;
     78         for (int i = 1; i <= n; ++i)
     79         {
     80             LL x, y, v;
     81             scanf("%lld %lld %lld", &x, &y, &v);
     82             line[++m] = Node(x*2-(W-1)+1, y*2-(H-1)+1, y*2+(H-1)-1, v);
     83             line[++m] = Node(x*2+(W-1), y*2-(H-1)+1, y*2+(H-1)-1, -v);
     84             t[++Tcnt] = y*2-(H-1)+1, t[++Tcnt] = y*2+(H-1)-1;
     85         }
     86         sort(t+1, t+Tcnt+1);
     87         int las_cnt = Tcnt;
     88         Tcnt = 0;
     89         for (int i = 1; i <= las_cnt; ++i)
     90             if (t[i] != t[i-1] || i == 1)
     91             {
     92                 t[++Tcnt] = t[i];
     93                 num_y[t[i]] = Tcnt;
     94             }
     95         sort(line+1, line+m+1);
     96         T.Build(1, 1, Tcnt);
     97         LL ans = 0;
     98         for (int i = 1; i <= m; ++i)
     99         {
    100             T.Update(1, 1, Tcnt, num_y[line[i].y1], num_y[line[i].y2], line[i].v);
    101             ans = max(ans, T.mv[1]);
    102         }
    103         printf("%lld
    ", ans);
    104     }
    105     return 0;
    106 }
    View Code
    Nothing is impossible!
  • 相关阅读:
    【宁夏区域赛】G.Pot!
    【C#】上机实验二
    【C#】上机实验三
    Luogu P1437 敲砖块
    Luogu P1463 反素数
    Luogu P1445 樱花
    GHOJ 926 小X的AK计划
    【题解】Beads
    【题解】Antisymmetry
    【题解】A Horrible Poem
  • 原文地址:https://www.cnblogs.com/-ZZB-/p/6379847.html
Copyright © 2011-2022 走看看