zoukankan      html  css  js  c++  java
  • UVAlive7141 BombX 14年上海区域赛D题 线段树+离散化

    题意:一个无限大的棋盘, 有n个小兵, 给出了n个兵的坐标, 现在有一个长为width 高为height的炸弹放在棋盘上, 炸弹只能上下左右平移, 不能旋转。

    且放炸弹的区域不能含有士兵, 炸弹可以一次炸掉与它同一行同一列的所有士兵。 放一颗炸弹, 使得炸死的士兵最多。输出最大值。

    思路:先不考虑离散化, 可以计算出水平方向和竖直方向上所有长度为width和height区间内士兵的个数, 得到一个数组prefixX, prefixY。

    然后一次遍历prefixY数组, 假设区间[i, i+height-1]对应prefixY[i], 而且[i, i+height-1]内所有士兵的x坐标对应的prefixX都减去一个大于n的数字MAX(这样保证炸弹不会放在士兵上),这个时候求prefixX上的一个最大值max再加上prefixY[i]就可以更新答案result了, 如果max是一个负数那么说明当前这个区间不能放炸弹。 之后再把第i行的所有士兵的x坐标对应的prefixX都加上MAX。 这样一次下去就可以了。线段树区间操作。

    还有一个需要特判的地方是 上面并没有找到一个可以放炸弹的地方。 这个时候答案就是prefixX和prefixY的最大值。

    思路一下子就想出来了,可是怎么离散化想了好久。。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int maxn = 2e5 + 5;
      4 struct SegTree{
      5     int seg[maxn << 2], lazy[maxn << 2];
      6     void build(int l, int r, int pos, int val[]){
      7         lazy[pos] = 0;
      8         if (l  == r){
      9             seg[pos] = val[l];
     10             return;
     11         }
     12         int mid = (l + r) >> 1;
     13         build(l, mid, pos<<1, val);
     14         build(mid+1, r, pos<<1|1, val);
     15         seg[pos] = max(seg[pos<<1], seg[pos<<1|1]);
     16     }
     17     void push_down(int pos){
     18         if (lazy[pos]){
     19             seg[pos<<1] += lazy[pos];
     20             seg[pos<<1|1] += lazy[pos];
     21             lazy[pos<<1] += lazy[pos];
     22             lazy[pos<<1|1] += lazy[pos];
     23             lazy[pos] = 0;
     24         }
     25     }
     26     void update (int l, int r, int pos, int ua, int ub, int val){
     27         if (ua > ub){
     28             return;
     29         }
     30         if (ua <= l && ub >= r){
     31             seg[pos] += val;
     32             lazy[pos] += val;
     33             return;
     34         }
     35         push_down(pos);
     36         int mid = (l + r) >> 1;
     37         if (ua <= mid){
     38             update(l, mid, pos<<1, ua, ub, val);
     39         }
     40         if (ub > mid){
     41             update(mid+1, r, pos<<1|1, ua, ub, val);
     42         }
     43         seg[pos] = max(seg[pos<<1], seg[pos<<1|1]);
     44     }
     45 }tree;
     46 int pawX[maxn], pawY[maxn];
     47 int lshX[maxn], lshY[maxn], tot1, tot2;
     48 int prefixX[maxn], prefixY[maxn], valX[maxn], valY[maxn];
     49 vector <int> vec1[maxn], vec2[maxn];
     50 void init(){
     51     memset(prefixX, 0, sizeof prefixX);
     52     memset(prefixY, 0, sizeof prefixY);
     53     for (int i = 0; i < maxn; i++){
     54         vec1[i].clear();
     55         vec2[i].clear();
     56     }
     57 }
     58 int main(){
     59     int T, cas = 1;
     60     scanf ("%d", &T);
     61     while (T--){
     62         int n, width, height;
     63         scanf ("%d%d%d", &n, &width, &height);
     64         tot1 = tot2 = 0;
     65         init();
     66         for (int i = 0; i < n; i++){
     67             int x, y;
     68             scanf ("%d%d", &x, &y);
     69             pawX[i] = x, pawY[i] = y;
     70             lshX[tot1++] = x;
     71             lshX[tot1++] = x - width+1;
     72             lshY[tot2++] = y;
     73             lshY[tot2++] = y-height+1;
     74         }
     75         sort(lshX, lshX+tot1);
     76         sort(lshY, lshY+tot2);
     77         tot1 = unique(lshX, lshX+tot1) - lshX;
     78         tot2 = unique(lshY, lshY+tot2) - lshY;
     79         for (int i = 0; i < n; i++){
     80             int x1 = lower_bound(lshX, lshX+tot1, pawX[i]-width+1) - lshX + 1;
     81             int x2 = lower_bound(lshX, lshX+tot1, pawX[i]) - lshX + 1;
     82             int y1 = lower_bound(lshY, lshY+tot2, pawY[i]-height+1) - lshY + 1;
     83             int y2 = lower_bound(lshY, lshY+tot2, pawY[i]) - lshY + 1;
     84             prefixX[x1]++; prefixX[x2+1]--;
     85             prefixY[y1]++; prefixY[y2+1]--;
     86             vec1[y1].push_back(i);
     87             vec2[y2].push_back(i);
     88         }
     89         int res = 0;
     90         for (int i = 1; i <= tot1; i++){
     91             prefixX[i] += prefixX[i-1];
     92             res = max(res, prefixX[i]);           // 这里要特判一下
     93         }
     94         for (int i = 1; i <= tot2; i++){
     95             prefixY[i] += prefixY[i-1];
     96             res = max(res, prefixY[i]);           // 这里要特判一下
     97         }
     98         tree.build(1, tot1, 1, prefixX);
     99         const int tenThousand = 1e5;
    100         for (int i = 1; i <= tot2; i++){
    101             for (int j = 0; j < vec1[i].size(); j++){
    102                 int idx = vec1[i][j];
    103                 int x = lower_bound(lshX, lshX+tot1, pawX[vec1[i][j]]) - lshX + 1;
    104                 int y = lower_bound(lshX, lshX+tot1, pawX[vec1[i][j]]-width+1) - lshX + 1;
    105                 tree.update(1, tot1, 1, y, x, -tenThousand);
    106             }
    107             int ret  = tree.seg[1];
    108             if (ret > 0)
    109                 res = max(res, prefixY[i]+ret);
    110             for (int j = 0; j < vec2[i].size(); j++){
    111                 int x = lower_bound(lshX, lshX+tot1, pawX[vec2[i][j]]) - lshX + 1;
    112                 int y = lower_bound(lshX, lshX+tot1, pawX[vec2[i][j]]-width+1) - lshX + 1;
    113                 tree.update(1, tot1, 1, y, x,  tenThousand);
    114             }
    115         }
    116         printf("Case #%d: %d
    ", cas++, res);
    117     }
    118     return 0;
    119 }
  • 相关阅读:
    c# 合并byte数组
    DataGridView扩展方法行号、全选、导出到Excel(引用excel组件、生成html两种方式)
    c#利用zlib.net对文件进行deflate流压缩(和java程序压缩生成一样)
    TSQL查询笔记4: FROM T1,T2与联接的区别
    “菜鸟”程序员和“大神”程序员差距在哪里
    JAVA:模板方法模式
    Windows检测到一个硬盘问题?
    照我思索,你的电脑百毒不侵 (转)
    JAVA:多态
    HTML与CSS(图解4):表格
  • 原文地址:https://www.cnblogs.com/oneshot/p/5001734.html
Copyright © 2011-2022 走看看