zoukankan      html  css  js  c++  java
  • BZOJ1218(线段树+扫描线)

    1.扫描线扫描x轴,线段树维护y轴。

    2.坐标+1,线段树是从1开始维护。然后让边长--,这样就能包含边上的点了。

    3.为了保证点在正方形内:在x轴上利用差分的思想,在x出Add(val),在x+r(已经-1了)处Add(-val);在y轴上利用线段树维护1~5001这个区间,在y~y+r上Add(val)。

    题解博客大家都是口胡感觉难以讲清这个事情,这篇博客虽然没解释但代码逻辑不错,看懂的。

      1 #pragma comment(linker, "/STACK:1024000000,1024000000")
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <cctype>
      8 #include <climits>
      9 #include <iostream>
     10 #include <iomanip>
     11 #include <algorithm>
     12 #include <string>
     13 #include <sstream>
     14 #include <stack>
     15 #include <queue>
     16 #include <set>
     17 #include <map>
     18 #include <vector>
     19 #include <list>
     20 #include <fstream>
     21 #include <bitset>
     22 #define init(a, b) memset(a, b, sizeof(a))
     23 #define rep(i, a, b) for (int i = a; i <= b; i++)
     24 #define irep(i, a, b) for (int i = a; i >= b; i--)
     25 #define ls(p)    p << 1
     26 #define rs(p)    p << 1 | 1
     27 using namespace std;
     28 
     29 typedef double db;
     30 typedef long long ll;
     31 typedef unsigned long long ull;
     32 typedef pair<int, int> P;
     33 const int inf = 0x3f3f3f3f;
     34 const ll INF = 1e18;
     35 
     36 template <typename T> void read(T &x) {
     37     x = 0;
     38     int s = 1, c = getchar();
     39     for (; !isdigit(c); c = getchar())
     40         if (c == '-')    s = -1;
     41     for (; isdigit(c); c = getchar())
     42         x = x * 10 + c - 48;
     43     x *= s;
     44 }
     45 
     46 template <typename T> void write(T x) {
     47     if (x < 0)    x = -x, putchar('-');
     48     if (x > 9)    write(x / 10);
     49     putchar(x % 10 + '0');
     50 }
     51 
     52 template <typename T> void writeln(T x) {
     53     write(x);
     54     puts("");
     55 }
     56 
     57 const int maxn = 1e4 + 5, M = 5001;
     58 int n, r, cnt;
     59 struct Seg {
     60     int l, r, mx, tag;
     61 }t[(M + 5) << 2];
     62 struct node {
     63     int x, y1, y2, val;
     64 }c[maxn << 1];
     65 
     66 void build(int l, int r, int p) {
     67     t[p].l = l, t[p].r = r;
     68     if (l == r) {
     69         t[p].mx = t[p].tag = 0;
     70         return;
     71     }
     72     int mid = (l + r) >> 1;
     73     build(l, mid, ls(p));
     74     build(mid + 1, r, rs(p));
     75 }
     76 
     77 void push_down(int p) {
     78     if (t[p].tag) {
     79         int tag = t[p].tag;
     80         t[ls(p)].mx += tag;
     81         t[rs(p)].mx += tag;
     82         t[ls(p)].tag += tag;
     83         t[rs(p)].tag += tag;
     84         t[p].tag = 0;
     85     }
     86 }
     87 
     88 void Add(int l, int r, int p, int k) {
     89     if (l <= t[p].l && t[p].r <= r) {
     90         t[p].tag += k;
     91         t[p].mx += k;
     92         return;
     93     }
     94     push_down(p);
     95     int mid = (t[p].l + t[p].r) >> 1;
     96     if (l <= mid)    Add(l, r, ls(p), k);
     97     if (mid < r)    Add(l, r, rs(p), k);
     98     t[p].mx = max(t[ls(p)].mx, t[rs(p)].mx);
     99 }
    100 
    101 int Query(int l, int r, int p) {
    102     if (l <= t[p].l && t[p].r <= r) {
    103         return t[p].mx;
    104     }
    105     push_down(p);
    106     int ret = 0;
    107     int mid = (t[p].l + t[p].r) >> 1;
    108     if (l <= mid)    ret = max(ret, Query(l, mid, ls(p)));
    109     if (mid < r)    ret = max(ret, Query(mid + 1, r, rs(p)));
    110     return ret;
    111 }
    112 
    113 bool cmp(node a, node b) {
    114     if (a.x != b.x)    return a.x < b.x;
    115     return a.val > b.val;
    116 }
    117 
    118 int solve() {
    119     int ans = 0;
    120     build(1, M, 1);
    121     rep(i, 1, n) {
    122         int x, y, z;
    123         read(x), read(y), read(z);
    124         c[++cnt] = {x + 1, y + 1, y + r, z};
    125         c[++cnt] = {x + r, y + 1, y + r, -z};
    126     }
    127     sort(c + 1, c + 1 + cnt, cmp);
    128 
    129     for (int i = 1, j, k; i <= cnt; i = j) {
    130         int tmp = c[i].x;
    131         for (j = i; j <= cnt && c[j].x == tmp; j++);
    132         for (k = i; k < j && c[k].val > 0; k++) {
    133             Add(c[k].y1, c[k].y2, 1, c[k].val);
    134         }
    135         ans = max(ans, Query(1, M, 1));
    136         for (; k < j; k++) {
    137             Add(c[k].y1, c[k].y2, 1, c[k].val);
    138         }
    139     }
    140     return ans;
    141 }
    142 
    143 int main() {
    144     read(n), read(r);
    145     writeln(solve());
    146     return 0;
    147 }
  • 相关阅读:
    Java 简单算法--打印乘法口诀(只使用一次循环)
    Java简单算法--求100以内素数
    ubuntu 16.04 chrome flash player 过期
    java 网络API访问 web 站点
    java scoket (UDP通信模型)简易聊天室
    leetcode1105 Filling Bookcase Shelves
    leetcode1140 Stone Game II
    leetcode1186 Maximum Subarray Sum with One Deletion
    leetcode31 Next Permutation
    leetcode834 Sum of Distances in Tree
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/10491569.html
Copyright © 2011-2022 走看看