Adding New Machine

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1428    Accepted Submission(s): 298

Problem Description
Incredible Crazily Progressing Company (ICPC) suffered a lot with the low speed of procedure. After investigation, they found that the bottleneck was at Absolutely Crowded Manufactory (ACM). In oder to accelerate the procedure, they bought a new machine for
ACM. But a new problem comes, how to place the new machine into ACM?

ACM is a rectangular factor and can be divided into W * H cells. There are N retangular old machines in ACM and the new machine can not occupy any cell where there is old machines. The new machine needs M consecutive cells. Consecutive cells means some adjacent
cells in a line. You are asked to calculate the number of ways to choose the place for the new machine. 

 
Input
There are multiple test cases (no more than 50). The first line of each test case contains 4 integers W, H, N, M (1 ≤ W, H ≤ 107, 0 ≤ N ≤ 50000, 1 ≤ M ≤ 1000), indicating the width and the length of the room, the number of old machines and the size
of the new machine. Then N lines follow, each of which contains 4 integers Xi1, Yi1, Xi2 and Yi2 (1 ≤ Xi1 ≤ Xi2 ≤ W, 1 ≤ Yi1 ≤ Yi2 ≤ H), indicating the coordinates of the
i-th old machine. It is guarantees that no cell is occupied by two old machines. 
 
Output
Output the number of ways to choose the cells to place the new machine in one line. 
 
Sample Input
  1. 3 3 1 2
  2. 2 2 2 2
  3. 3 3 1 3
  4. 2 2 2 2
  5. 2 3 2 2
  6. 1 1 1 1
  7. 2 3 2 3

 Sample Output

  1. 8
  2. 4
  3. 3
  1. /*
  2. hdu 4052 线段树扫描线、奇特处理
  3.  
  4. 给你W*H大小的矩形,其中有N个地区不能使用(给出了这个地区的两个顶点的坐标即(x1,y1)
  5. 和(x2,y2)),问能下多少个1*M的矩形。
  6.  
  7. 但是看见题目有想到了扫描线,但是一直不知道应该怎么处理后来偶然看见别人提示可以转换
  8. 成求面积,大致就有了思路
  9.  
  10. 假设1*n的矩阵中放入1*m的矩阵,能有多少种? n-m+1
  11. 我们扫描每一列,两个相邻为n的旧机器中就能放下n-m+1个新机器,于是原先的旧机器矩形
  12. 就变成了(x1,y1,x2+ma-1,y2)(从下往上扫描)
  13. (x1,y1,x2,y2+ma-1)(从左往右扫描)
  14. 而剩下的为被占据的位置就是方案数了
  15. 因为我是在每个旧机器往右边添加的,所以还要解决这一列没有从1开始的情况,所以在最左边
  16. 加上(1,1,ma,h+1)的矩阵
  17. 而且ma=1时,横着放和竖着放是一样的,所以除以2
  18.  
  19. 但是第一个版本写出来一直 RuntimeError
  20. 后来实在没法又换了个,把离散化用vec处理终于出现了WR(TAT)
  21. 主要是 ma == 1 情况,因为我会在1添加一个矩阵,但是当ma==1时这个矩阵也被建立了就导致
  22. (1,1,1,h+1) 由于是按边建树l=x1,r=x2-1 -> r<l (- -!好气) //应该多测几次的
  23.  
  24. 然后进行了特判第一个也过了
  25.  
  26. hhh-2016-03-30 22:26:25
  27. */
  28.  
  29. //Second
  30. #include <iostream>
  31. #include <cstdio>
  32. #include <string>
  33. #include <cstdlib>
  34. #include <functional>
  35. #include <map>
  36. #include <algorithm>
  37. #include <queue>
  38. #include <vector>
  39. #define lson (i<<1)
  40. #define rson ((i<<1)|1)
  41. typedef long long ll;
  42. using namespace std;
  43.  
  44. const int maxn = 1000005;
  45. vector<int> vec;
  46. int w,h;
  47. int x[maxn],y[maxn],tx[maxn],ty[maxn];
  48. map<int,int > mp;
  49. int n,ma;
  50. struct node
  51. {
  52. int l,r;
  53. int sum;
  54. ll len;
  55. int mid()
  56. {
  57. return (l+r)>>1;
  58. }
  59. } tree[maxn<<2];
  60.  
  61. void push_up(int i)
  62. {
  63. if(tree[i].sum)
  64. tree[i].len = vec[tree[i].r+1]-vec[tree[i].l];
  65. else if(tree[i].l == tree[i].r)
  66. tree[i].len = 0;
  67. else
  68. tree[i].len = tree[lson].len+tree[rson].len;
  69. }
  70.  
  71. void build(int i,int l,int r)
  72. {
  73. tree[i].l = l,tree[i].r = r;
  74. tree[i].sum = tree[i].len = 0;
  75. if(l == r)
  76. return;
  77. build(lson,l,tree[i].mid());
  78. build(rson,tree[i].mid()+1,r);
  79. push_up(i);
  80. }
  81.  
  82. void push_down(int i)
  83. {
  84.  
  85. }
  86.  
  87. void Insert(int i,int l,int r,int val)
  88. {
  89. if(tree[i].l >= l && tree[i].r <= r)
  90. {
  91. tree[i].sum += val;
  92. push_up(i);
  93. return ;
  94. }
  95. int mid = tree[i].mid();
  96. push_down(i);
  97. if(l <= mid)
  98. Insert(lson,l,r,val);
  99. if(r > mid)
  100. Insert(rson,l,r,val);
  101. push_up(i);
  102. return ;
  103. }
  104.  
  105. struct edge
  106. {
  107. int l,r;
  108. int high;
  109. int va;
  110. };
  111. edge Line[maxn<<2];
  112. int m;
  113. bool cmp(edge a,edge b)
  114. {
  115. if(a.high != b.high)
  116. return a.high < b.high;
  117. else
  118. return a.va > b.va;
  119. }
  120.  
  121. int tox;
  122. ll ans;
  123. void solve(int cur,int hi,int wi)
  124. {
  125. vec.clear();
  126. if(cur)
  127. {
  128. for(int i =1; i <= n; i++)
  129. swap(x[i],y[i]),swap(tx[i],ty[i]);
  130. }
  131. tox = 0;
  132. for(int i = 1; i <= n; i++)
  133. {
  134. int t = min(wi+1,tx[i]+ma-1);
  135. Line[tox].l = x[i],Line[tox].r =t,Line[tox].high = y[i],Line[tox++].va = 1;
  136. Line[tox].l = x[i],Line[tox].r =t,Line[tox].high = ty[i],Line[tox++].va = -1;
  137. vec.push_back(x[i]);
  138. vec.push_back(t);
  139. }
  140. if(ma != 1)
  141. {
  142. Line[tox].l = 1,Line[tox].r = ma,Line[tox].high=1,Line[tox++].va=1;
  143. Line[tox].l = 1,Line[tox].r = ma,Line[tox].high=hi+1,Line[tox++].va=-1;
  144. vec.push_back(1),vec.push_back(ma);
  145. }
  146. sort(Line,Line+tox,cmp);
  147. sort(vec.begin(),vec.end());
  148. vec.erase(unique(vec.begin(),vec.end()),vec.end());
  149. int m = vec.size();
  150. for(int i = 0; i < m; i++)
  151. mp[vec[i]] = i;
  152. build(1,0,m);
  153. int l,r;
  154. for(int i = 0; i < tox-1; i++)
  155. {
  156. l = mp[Line[i].l];
  157. r = mp[Line[i].r]-1;
  158. if(r < l)
  159. continue;
  160. Insert(1,l,r,Line[i].va);
  161. ans -= (ll)tree[1].len*(Line[i+1].high-Line[i].high);
  162. }
  163. //cout << tans <<endl;
  164. }
  165.  
  166. int main()
  167. {
  168. while(scanf("%d%d%d%d",&w,&h,&n,&ma) != EOF)
  169. {
  170. for(int i = 1; i <= n; i++)
  171. {
  172. scanf("%d%d%d%d",&x[i],&y[i],&tx[i],&ty[i]);
  173. tx[i]++,ty[i]++;
  174. }
  175.  
  176. ans =(ll)w*h*2;
  177. solve(0,h,w);
  178. solve(1,w,h);
  179. if(ma == 1)
  180. ans /= 2;
  181. printf("%I64d\n",ans);
  182. }
  183. return 0;
  184. }
  185.  
  186. /*
  187. First:
  188.  
  189. #include <iostream>
  190. #include <cstdio>
  191. #include <string>
  192. #include <cstdlib>
  193. #include <functional>
  194. #include <map>
  195. #include <algorithm>
  196. #include <queue>
  197.  
  198. #define lson (i<<1)
  199. #define rson ((i<<1)|1)
  200. typedef long long ll;
  201. using namespace std;
  202.  
  203. const int maxn = 1000005;
  204.  
  205. ll w,h;
  206. int n,ma;
  207. int now;
  208. struct node
  209. {
  210. int l,r;
  211. int sum;
  212. ll len;
  213. int mid()
  214. {
  215. return (l+r)>>1;
  216. }
  217. } tree[maxn<<2];
  218. ll hs[2][maxn];
  219.  
  220. void push_up(int i)
  221. {
  222. if(tree[i].sum)
  223. tree[i].len = hs[now][tree[i].r+1]-hs[now][tree[i].l];
  224. else if(tree[i].l == tree[i].r)
  225. tree[i].len = 0;
  226. else
  227. tree[i].len = tree[lson].len+tree[rson].len;
  228. }
  229.  
  230. void build(int i,int l,int r)
  231. {
  232. tree[i].l = l,tree[i].r = r;
  233. tree[i].sum = tree[i].len = 0;
  234. if(l == r)
  235. return;
  236. build(lson,l,tree[i].mid());
  237. build(rson,tree[i].mid()+1,r);
  238. push_up(i);
  239. }
  240.  
  241. void push_down(int i)
  242. {
  243.  
  244. }
  245.  
  246. void Insert(int i,int l,int r,int val)
  247. {
  248. if(tree[i].l >= l && tree[i].r <= r)
  249. {
  250. tree[i].sum += val;
  251. push_up(i);
  252. return ;
  253. }
  254. int mid = tree[i].mid();
  255. push_down(i);
  256. if(l <= mid)
  257. Insert(lson,l,r,val);
  258. if(r > mid)
  259. Insert(rson,l,r,val);
  260. push_up(i);
  261. return ;
  262. }
  263.  
  264. struct edge
  265. {
  266. ll l,r;
  267. ll high;
  268. int va;
  269. };
  270. edge tx[maxn<<2];
  271. edge ty[maxn<<2];
  272. int m;
  273. bool cmp(edge a,edge b)
  274. {
  275. if(a.high != b.high)
  276. return a.high < b.high;
  277. else
  278. return a.va > b.va;
  279. }
  280. int bin(int cur,ll x)
  281. {
  282. int l = 0,r = m-1;
  283. while(l <= r)
  284. {
  285. int mid = (l+r)>>1;
  286. if(hs[cur][mid] == x)
  287. return mid;
  288. else if(hs[cur][mid] < x)
  289. l = mid+1;
  290. else
  291. r = mid-1;
  292. }
  293. }
  294. int tox,toy;
  295. ll solve(int cur)
  296. {
  297. now = cur;
  298. int len = (cur == 0 ? tox:toy);
  299. m = 1;
  300. for(int i = 1; i < len; i++) //ШЅжи
  301. {
  302. if(hs[cur][i] != hs[cur][i-1])
  303. hs[cur][m++] = hs[cur][i];
  304. }
  305. // for(int i = 0;i < m;i++)
  306. // printf("%d ",hs[cur][i]);
  307. // cout <<endl;
  308. build(1,0,m);
  309. ll tans = 0;
  310. int l,r;
  311. for(int i = 0; i < len-1; i++)
  312. {
  313. if(cur == 0)
  314. {
  315. l = bin(cur,tx[i].l);
  316. r = bin(cur,tx[i].r)-1;
  317. Insert(1,l,r,tx[i].va);
  318. tans += (ll)tree[1].len*(tx[i+1].high-tx[i].high);
  319. }
  320. else
  321. {
  322. l = bin(cur,ty[i].l);
  323. r = bin(cur,ty[i].r)-1;
  324. if(r < l )continue;
  325. Insert(1,l,r,ty[i].va);
  326. tans += (ll)tree[1].len*(ty[i+1].high-ty[i].high);
  327. }
  328.  
  329. //cout << tree[i].len << endl;
  330. //cout << tans <<endl;
  331.  
  332. }
  333. //cout << tans <<endl;
  334. return tans;
  335. }
  336.  
  337. int main()
  338. {
  339. while(scanf("%I64d%I64d%d%d",&w,&h,&n,&ma) != EOF)
  340. {
  341. tox = 0,toy = 0;
  342. ll x1,y1,x2,y2;
  343. for(int i = 1; i <= n; i++)
  344. {
  345. scanf("%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2);
  346. x2++,y2++;
  347. ll t1 = (x2+ma-1)>w+1? w+1:x2+ma-1;
  348. tx[tox].l = x1,tx[tox].r = t1,tx[tox].high = y1,tx[tox].va = 1;
  349. hs[0][tox++] = x1;
  350. tx[tox].l = x1,tx[tox].r = t1,tx[tox].high = y2,tx[tox].va = -1;
  351. hs[0][tox++] = t1;
  352.  
  353. t1 = (y2+ma-1)>h+1? h+1:y2+ma-1;
  354. ty[toy].l = y1,ty[toy].r = t1,ty[toy].high = x1,ty[toy].va = 1;
  355. hs[1][toy++] = y1;
  356. ty[toy].l = y1,ty[toy].r = t1,ty[toy].high = x2,ty[toy].va = -1;
  357. hs[1][toy++] = t1;
  358. }
  359. if(ma != 1){
  360. tx[tox].l = 1,tx[tox].r = ma,ty[toy].l=1,ty[toy].r = ma;
  361. tx[tox].high=1,tx[tox].va=1,ty[toy].high=1,ty[toy].va=1;
  362. hs[0][tox++] = 1,hs[1][toy++]=1;
  363.  
  364. tx[tox].l = 1,tx[tox].r = ma,ty[toy].l=1,ty[toy].r = ma;
  365. tx[tox].high=h+1,tx[tox].va=-1,ty[toy].high=w+1,ty[toy].va=-1;
  366. hs[0][tox++] = ma,hs[1][toy++] = ma;
  367. }
  368. sort(hs[0],hs[0]+tox);
  369. sort(hs[1],hs[1]+toy);
  370. sort(tx,tx+tox,cmp);
  371. sort(ty,ty+toy,cmp);
  372. ll ans = w*h*2;
  373.  
  374. ans -= solve(0);
  375. //printf("%I64d\n",ans);
  376. ans -= solve(1);
  377. if(ma == 1)
  378. ans /= 2;
  379. printf("%I64d\n",ans);
  380. }
  381. return 0;
  382. }
  383.  
  384. */

  

  1.  

hdu 4052 线段树扫描线、奇特处理的更多相关文章

  1. hdu 1828 线段树扫描线(周长)

    Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  2. hdu 5091(线段树+扫描线)

    上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...

  3. HDU 5107 线段树扫描线

    给出N个点(x,y).每一个点有一个高度h 给出M次询问.问在(x,y)范围内第k小的高度是多少,没有输出-1 (k<=10) 线段树扫描线 首先离散化Y坐标,以Y坐标建立线段树 对全部的点和询 ...

  4. hdu 1255(线段树 扫描线) 覆盖的面积

    http://acm.hdu.edu.cn/showproblem.php?pid=1255 典型线段树辅助扫描线,顾名思义扫描线就是相当于yy出一条直线从左到右(也可以从上到下)扫描过去,此时先将所 ...

  5. HDU 5091 线段树扫描线

    给出N个点.和一个w*h的矩形 给出N个点的坐标,求该矩形最多能够覆盖多少个点 对每一个点point(x.y)右边生成相应的点(x+w,y)值为-1: 纵向建立线段树,从左到右扫描线扫一遍.遇到点则用 ...

  6. hdu 1542 线段树+扫描线 学习

    学习扫描线ing... 玄学的东西... 扫描线其实就是用一条假想的线去扫描一堆矩形,借以求出他们的面积或周长(这一篇是面积,下一篇是周长) 扫描线求面积的主要思想就是对一个二维的矩形的某一维上建立一 ...

  7. hdu 4419 线段树 扫描线 离散化 矩形面积

    //离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...

  8. hdu 3265 线段树扫描线(拆分矩形)

    题意:        给你n个矩形,每个矩形上都有一个矩形的空洞,所有的矩形都是平行于x,y轴的,最后问所有矩形的覆盖面积是多少. 思路:       是典型的矩形覆盖问题,只不过每个矩形上多了一个矩 ...

  9. HDU 1828 线段树+扫描线(计算矩形周长并)

    题意:给你n个矩形,然后矩形有可能重叠,要你求周长 思路:首先碰到这种矩形在数轴上那么第一反应应该想到的是扫描线, 做周长我们有两种方法 第一种,我们可以分开两部分求,第一遍求x轴上的贡献,第二遍求y ...

随机推荐

  1. python的迭代器、生成器、装饰器

    迭代器.生成器.装饰器 在这个实验里我们学习迭代器.生成器.装饰器有关知识. 知识点 迭代器 生成器 生成器表达式 闭包 装饰器 实验步骤 1. 迭代器 Python 迭代器(Iterators)对象 ...

  2. 使用SecureCRTP 连接生产环境的web服务器和数据库服务器

    一.使用SecureCRTP 连接生产环境的web服务器 首先,需要知道以下参数信息: 1.web服务器的ip地址     2.服务器的端口号    3.会话连接的用户名和密码   4.服务器的用户名 ...

  3. mysql命令行大全

      1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root ...

  4. git cherry-pick 整理

    git cherry-pick可以选择某一个分支中的一个或几个commit(s)来进行操作.例如,假设我们有个稳定版本的分支,叫v2.0,另外还有个开发版本的分支v3.0,我们不能直接把两个分支合并, ...

  5. 【漏洞复现】PHPCMS wap模块 SQL注入(附EXP)

    漏洞影响版本:v9.5.8.v9.6.0 Step1: 访问:http://www.xxx.com/index.php?m=wap&a=index&siteid=1, 获取返回的coo ...

  6. 新概念英语(1-1)Excuse me!

    Excuse me!Whose handbag is it? A:Excuse me! B:Yes? A:Is this your handbag? B:Pardon? A:Is this your ...

  7. css(1-1)样式表

    CSS Id 和 Class id 和 class 选择器 如果你要在HTML元素中设置CSS样式,你需要在元素中设置"id" 和 "class"选择器. id ...

  8. PL/SQL Developer 导入导出操作

    一.PL/SQL Developer数据导入 Tools->Import Tables

  9. git初试

    在gitLab上新建一个项目,creat项目文件之后,进入到项目的路径之后,复制命令git clone ‘git@gitlab.touzila.com:xiacaixiang/gitgitTest1. ...

  10. Java-NIO(四):通道(Channel)的原理与获取

    通道(Channel): 由java.nio.channels包定义的,Channel表示IO源与目标打开的连接,Channel类似于传统的“流”,只不过Channel本身不能直接访问数据,Chann ...