题意:一个无限大的棋盘, 有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 + ;
  4. struct SegTree{
  5. int seg[maxn << ], lazy[maxn << ];
  6. void build(int l, int r, int pos, int val[]){
  7. lazy[pos] = ;
  8. if (l == r){
  9. seg[pos] = val[l];
  10. return;
  11. }
  12. int mid = (l + r) >> ;
  13. build(l, mid, pos<<, val);
  14. build(mid+, r, pos<<|, val);
  15. seg[pos] = max(seg[pos<<], seg[pos<<|]);
  16. }
  17. void push_down(int pos){
  18. if (lazy[pos]){
  19. seg[pos<<] += lazy[pos];
  20. seg[pos<<|] += lazy[pos];
  21. lazy[pos<<] += lazy[pos];
  22. lazy[pos<<|] += lazy[pos];
  23. lazy[pos] = ;
  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) >> ;
  37. if (ua <= mid){
  38. update(l, mid, pos<<, ua, ub, val);
  39. }
  40. if (ub > mid){
  41. update(mid+, r, pos<<|, ua, ub, val);
  42. }
  43. seg[pos] = max(seg[pos<<], seg[pos<<|]);
  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, , sizeof prefixX);
  52. memset(prefixY, , sizeof prefixY);
  53. for (int i = ; i < maxn; i++){
  54. vec1[i].clear();
  55. vec2[i].clear();
  56. }
  57. }
  58. int main(){
  59. int T, cas = ;
  60. scanf ("%d", &T);
  61. while (T--){
  62. int n, width, height;
  63. scanf ("%d%d%d", &n, &width, &height);
  64. tot1 = tot2 = ;
  65. init();
  66. for (int i = ; 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+;
  72. lshY[tot2++] = y;
  73. lshY[tot2++] = y-height+;
  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 = ; i < n; i++){
  80. int x1 = lower_bound(lshX, lshX+tot1, pawX[i]-width+) - lshX + ;
  81. int x2 = lower_bound(lshX, lshX+tot1, pawX[i]) - lshX + ;
  82. int y1 = lower_bound(lshY, lshY+tot2, pawY[i]-height+) - lshY + ;
  83. int y2 = lower_bound(lshY, lshY+tot2, pawY[i]) - lshY + ;
  84. prefixX[x1]++; prefixX[x2+]--;
  85. prefixY[y1]++; prefixY[y2+]--;
  86. vec1[y1].push_back(i);
  87. vec2[y2].push_back(i);
  88. }
  89. int res = ;
  90. for (int i = ; i <= tot1; i++){
  91. prefixX[i] += prefixX[i-];
  92. res = max(res, prefixX[i]); // 这里要特判一下
  93. }
  94. for (int i = ; i <= tot2; i++){
  95. prefixY[i] += prefixY[i-];
  96. res = max(res, prefixY[i]); // 这里要特判一下
  97. }
  98. tree.build(, tot1, , prefixX);
  99. const int tenThousand = 1e5;
  100. for (int i = ; i <= tot2; i++){
  101. for (int j = ; j < vec1[i].size(); j++){
  102. int idx = vec1[i][j];
  103. int x = lower_bound(lshX, lshX+tot1, pawX[vec1[i][j]]) - lshX + ;
  104. int y = lower_bound(lshX, lshX+tot1, pawX[vec1[i][j]]-width+) - lshX + ;
  105. tree.update(, tot1, , y, x, -tenThousand);
  106. }
  107. int ret = tree.seg[];
  108. if (ret > )
  109. res = max(res, prefixY[i]+ret);
  110. for (int j = ; j < vec2[i].size(); j++){
  111. int x = lower_bound(lshX, lshX+tot1, pawX[vec2[i][j]]) - lshX + ;
  112. int y = lower_bound(lshX, lshX+tot1, pawX[vec2[i][j]]-width+) - lshX + ;
  113. tree.update(, tot1, , y, x, tenThousand);
  114. }
  115. }
  116. printf("Case #%d: %d\n", cas++, res);
  117. }
  118. return ;
  119. }

UVAlive7141 BombX 14年上海区域赛D题 线段树+离散化的更多相关文章

  1. UVALive 7148 LRIP 14年上海区域赛K题 树分治

    题意 n个点组成一棵树, 带有点权. 求最长不降的路径的长度, 且路径上最大值最小值之差不超过D. 显然是树分治, 但是分治之后如何维护答案呢. 假设当前重心为g, 分别记录g出发不降路径的长度,以及 ...

  2. hdu 5475 模拟计算器乘除 (2015上海网赛H题 线段树)

    给出有多少次操作 和MOD 初始值为1 操作1 y 表示乘上y操作2 y 表示除以第 y次操作乘的那个数 线段树的叶子结点i 表示 第i次操作乘的数 将1替换成y遇到操作2 就把第i个结点的值 替换成 ...

  3. ACM 2015年上海区域赛A题 HDU 5572An Easy Physics Problem

    题意: 光滑平面,一个刚性小球,一个固定的刚性圆柱体 ,给定圆柱体圆心坐标,半径 ,小球起点坐标,起始运动方向(向量) ,终点坐标 ,问能否到达终点,小球运动中如果碰到圆柱体会反射. 学到了向量模板, ...

  4. UVALive 8519 Arrangement for Contests 2017西安区域赛H 贪心+线段树优化

    题意 等价于给一个数列,每次对一个长度为$K$的连续区间减一 为最多操作多少次 题解: 看样例猜的贪心,10分钟敲了个线段树就交了... 从1开始,找$[i,i+K]$区间的最小值,然后区间减去最小值 ...

  5. hdu 4031 2011成都赛区网络赛A题 线段树 ***

    就是不知道时间该怎么处理,想了好久,看了别人的题解发现原来是暴力,暴力也很巧妙啊,想不出来的那种  -_-! #include<cstdio> #include<iostream&g ...

  6. HDU - 6521 Party (SYSU校赛K题)(线段树)

    题目链接 题意:n个人排成一列,一开始他们互不认识,每次选[l,r]上的人开party,使他们互相认识,求出每次party之后新互相认识的人的对数. 思路:把“互相认识”变成单向连边,只考虑左边的人对 ...

  7. 2019 ICPC 上海区域赛总结

    2019上海区域赛现场赛总结 补题情况(以下通过率为牛客提交): 题号 标题 已通过代码 通过率 我的状态 A Mr. Panda and Dominoes 点击查看 5/29 未通过 B Prefi ...

  8. HDU-5532//2015ACM/ICPC亚洲区长春站-重现赛-F - Almost Sorted Array/,哈哈,水一把区域赛的题~~

    F - Almost Sorted Array Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & ...

  9. hdu5080:几何+polya计数(鞍山区域赛K题)

    /* 鞍山区域赛的K题..当时比赛都没来得及看(反正看了也不会) 学了polya定理之后就赶紧跑来补这个题.. 由于几何比较烂写了又丑又长的代码,还debug了很久.. 比较感动的是竟然1Y了.. * ...

随机推荐

  1. NSAttributedString用法

    以前看到这种字号和颜色不一样的字符串,想出个讨巧的办法就是“¥150”一个UILabel,“元/位”一个UILabel.今天翻看以前的工程,command点进UITextField中看到[attrib ...

  2. C# 基础 知识点

    类型 1.decimal为高精度浮点数,常用于货币计算,然后它不是基本类型,所以性能相对float和double要差. 2.@用于字符串前使转义字符 \  无效,甚至能将回车当作换行符直接赋值给字符串 ...

  3. Linq 构造复杂Json 多表group by

    一个主表A(a1,a2),子表B(a1,b1,b2) ,想得到的结果是 [{a1,a2,Info [{b1,b2},{b1,b2},...}]] var list= from a in A join ...

  4. 单页应用引擎的写法artTemplate

    使用到了ba-haschange.js <script src="../style/js/plugin/template-native-debug.js"></s ...

  5. WAMP(Windows+Apache+Mysql+PHP)环境搭建

    学习PHP已经有一段时间,一直没有写过关于开发环境搭建的笔记,现在补上吧,因为安装配置的步骤记得不是很清楚,借鉴了一些别人的经验,总结如下: 首先去官方网站下载各个软件,下载需要的版本: Apache ...

  6. Object之克隆对象clone 和__clone()函数

    在前面的PHP面向对象之对象和引用,"$b=$a"的方式复制对象传递的是对象的地址,而不是传递对象的值(内容),我们可以通过克隆对象来实现对对象的内容和引用的复制 使用传址引用的方 ...

  7. VC杂记

    获得Combobox的状态:向ComboBox发送CB_GETDROPPEDSTATE消息. 格式化字串:char buff[10] ; sprintf(buff,"1+1=%d" ...

  8. IOS 项目名称修改(XCODE4.6)

    最近为了保存苹果商店已有版本软件,打算重新上传一个程序,与原来的软件仅样式不同.在修改网plist文件中的名称后,archive时报错了,结果发现时工程名称没有修改到.下面就与大家分享下修改已有项目名 ...

  9. Linux Curses编程实现贪吃蛇

    curses库 简单而言,提供UNIX中多种终端 操作光标和显示字符 的接口.我们常见的vi就是使用curses实现的.现在一般都用ncurses库. Linux下curses函数库    Linux ...

  10. AVR GCC对端口的操作指南

    1. AVR GCC for AVR I.I/O端口API1. BV用法:BV(pos);说明:将位定义转换成屏蔽码(MASK).与头文件io.h里的位定义一起使用.例如,置位WDTOE和WDE可表示 ...