hdu 4052 线段树扫描线、奇特处理
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
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.
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.
- 3 3 1 2
- 2 2 2 2
- 3 3 1 3
- 2 2 2 2
- 2 3 2 2
- 1 1 1 1
- 2 3 2 3
Sample Output
- 8
- 4
- 3
- /*
- hdu 4052 线段树扫描线、奇特处理
- 给你W*H大小的矩形,其中有N个地区不能使用(给出了这个地区的两个顶点的坐标即(x1,y1)
- 和(x2,y2)),问能下多少个1*M的矩形。
- 但是看见题目有想到了扫描线,但是一直不知道应该怎么处理后来偶然看见别人提示可以转换
- 成求面积,大致就有了思路
- 假设1*n的矩阵中放入1*m的矩阵,能有多少种? n-m+1
- 我们扫描每一列,两个相邻为n的旧机器中就能放下n-m+1个新机器,于是原先的旧机器矩形
- 就变成了(x1,y1,x2+ma-1,y2)(从下往上扫描)
- (x1,y1,x2,y2+ma-1)(从左往右扫描)
- 而剩下的为被占据的位置就是方案数了
- 因为我是在每个旧机器往右边添加的,所以还要解决这一列没有从1开始的情况,所以在最左边
- 加上(1,1,ma,h+1)的矩阵
- 而且ma=1时,横着放和竖着放是一样的,所以除以2
- 但是第一个版本写出来一直 RuntimeError
- 后来实在没法又换了个,把离散化用vec处理终于出现了WR(TAT)
- 主要是 ma == 1 情况,因为我会在1添加一个矩阵,但是当ma==1时这个矩阵也被建立了就导致
- (1,1,1,h+1) 由于是按边建树l=x1,r=x2-1 -> r<l (- -!好气) //应该多测几次的
- 然后进行了特判第一个也过了
- hhh-2016-03-30 22:26:25
- */
- //Second
- #include <iostream>
- #include <cstdio>
- #include <string>
- #include <cstdlib>
- #include <functional>
- #include <map>
- #include <algorithm>
- #include <queue>
- #include <vector>
- #define lson (i<<1)
- #define rson ((i<<1)|1)
- typedef long long ll;
- using namespace std;
- const int maxn = 1000005;
- vector<int> vec;
- int w,h;
- int x[maxn],y[maxn],tx[maxn],ty[maxn];
- map<int,int > mp;
- int n,ma;
- struct node
- {
- int l,r;
- int sum;
- ll len;
- int mid()
- {
- return (l+r)>>1;
- }
- } tree[maxn<<2];
- void push_up(int i)
- {
- if(tree[i].sum)
- tree[i].len = vec[tree[i].r+1]-vec[tree[i].l];
- else if(tree[i].l == tree[i].r)
- tree[i].len = 0;
- else
- tree[i].len = tree[lson].len+tree[rson].len;
- }
- void build(int i,int l,int r)
- {
- tree[i].l = l,tree[i].r = r;
- tree[i].sum = tree[i].len = 0;
- if(l == r)
- return;
- build(lson,l,tree[i].mid());
- build(rson,tree[i].mid()+1,r);
- push_up(i);
- }
- void push_down(int i)
- {
- }
- void Insert(int i,int l,int r,int val)
- {
- if(tree[i].l >= l && tree[i].r <= r)
- {
- tree[i].sum += val;
- push_up(i);
- return ;
- }
- int mid = tree[i].mid();
- push_down(i);
- if(l <= mid)
- Insert(lson,l,r,val);
- if(r > mid)
- Insert(rson,l,r,val);
- push_up(i);
- return ;
- }
- struct edge
- {
- int l,r;
- int high;
- int va;
- };
- edge Line[maxn<<2];
- int m;
- bool cmp(edge a,edge b)
- {
- if(a.high != b.high)
- return a.high < b.high;
- else
- return a.va > b.va;
- }
- int tox;
- ll ans;
- void solve(int cur,int hi,int wi)
- {
- vec.clear();
- if(cur)
- {
- for(int i =1; i <= n; i++)
- swap(x[i],y[i]),swap(tx[i],ty[i]);
- }
- tox = 0;
- for(int i = 1; i <= n; i++)
- {
- int t = min(wi+1,tx[i]+ma-1);
- Line[tox].l = x[i],Line[tox].r =t,Line[tox].high = y[i],Line[tox++].va = 1;
- Line[tox].l = x[i],Line[tox].r =t,Line[tox].high = ty[i],Line[tox++].va = -1;
- vec.push_back(x[i]);
- vec.push_back(t);
- }
- if(ma != 1)
- {
- Line[tox].l = 1,Line[tox].r = ma,Line[tox].high=1,Line[tox++].va=1;
- Line[tox].l = 1,Line[tox].r = ma,Line[tox].high=hi+1,Line[tox++].va=-1;
- vec.push_back(1),vec.push_back(ma);
- }
- sort(Line,Line+tox,cmp);
- sort(vec.begin(),vec.end());
- vec.erase(unique(vec.begin(),vec.end()),vec.end());
- int m = vec.size();
- for(int i = 0; i < m; i++)
- mp[vec[i]] = i;
- build(1,0,m);
- int l,r;
- for(int i = 0; i < tox-1; i++)
- {
- l = mp[Line[i].l];
- r = mp[Line[i].r]-1;
- if(r < l)
- continue;
- Insert(1,l,r,Line[i].va);
- ans -= (ll)tree[1].len*(Line[i+1].high-Line[i].high);
- }
- //cout << tans <<endl;
- }
- int main()
- {
- while(scanf("%d%d%d%d",&w,&h,&n,&ma) != EOF)
- {
- for(int i = 1; i <= n; i++)
- {
- scanf("%d%d%d%d",&x[i],&y[i],&tx[i],&ty[i]);
- tx[i]++,ty[i]++;
- }
- ans =(ll)w*h*2;
- solve(0,h,w);
- solve(1,w,h);
- if(ma == 1)
- ans /= 2;
- printf("%I64d\n",ans);
- }
- return 0;
- }
- /*
- First:
- #include <iostream>
- #include <cstdio>
- #include <string>
- #include <cstdlib>
- #include <functional>
- #include <map>
- #include <algorithm>
- #include <queue>
- #define lson (i<<1)
- #define rson ((i<<1)|1)
- typedef long long ll;
- using namespace std;
- const int maxn = 1000005;
- ll w,h;
- int n,ma;
- int now;
- struct node
- {
- int l,r;
- int sum;
- ll len;
- int mid()
- {
- return (l+r)>>1;
- }
- } tree[maxn<<2];
- ll hs[2][maxn];
- void push_up(int i)
- {
- if(tree[i].sum)
- tree[i].len = hs[now][tree[i].r+1]-hs[now][tree[i].l];
- else if(tree[i].l == tree[i].r)
- tree[i].len = 0;
- else
- tree[i].len = tree[lson].len+tree[rson].len;
- }
- void build(int i,int l,int r)
- {
- tree[i].l = l,tree[i].r = r;
- tree[i].sum = tree[i].len = 0;
- if(l == r)
- return;
- build(lson,l,tree[i].mid());
- build(rson,tree[i].mid()+1,r);
- push_up(i);
- }
- void push_down(int i)
- {
- }
- void Insert(int i,int l,int r,int val)
- {
- if(tree[i].l >= l && tree[i].r <= r)
- {
- tree[i].sum += val;
- push_up(i);
- return ;
- }
- int mid = tree[i].mid();
- push_down(i);
- if(l <= mid)
- Insert(lson,l,r,val);
- if(r > mid)
- Insert(rson,l,r,val);
- push_up(i);
- return ;
- }
- struct edge
- {
- ll l,r;
- ll high;
- int va;
- };
- edge tx[maxn<<2];
- edge ty[maxn<<2];
- int m;
- bool cmp(edge a,edge b)
- {
- if(a.high != b.high)
- return a.high < b.high;
- else
- return a.va > b.va;
- }
- int bin(int cur,ll x)
- {
- int l = 0,r = m-1;
- while(l <= r)
- {
- int mid = (l+r)>>1;
- if(hs[cur][mid] == x)
- return mid;
- else if(hs[cur][mid] < x)
- l = mid+1;
- else
- r = mid-1;
- }
- }
- int tox,toy;
- ll solve(int cur)
- {
- now = cur;
- int len = (cur == 0 ? tox:toy);
- m = 1;
- for(int i = 1; i < len; i++) //ШЅжи
- {
- if(hs[cur][i] != hs[cur][i-1])
- hs[cur][m++] = hs[cur][i];
- }
- // for(int i = 0;i < m;i++)
- // printf("%d ",hs[cur][i]);
- // cout <<endl;
- build(1,0,m);
- ll tans = 0;
- int l,r;
- for(int i = 0; i < len-1; i++)
- {
- if(cur == 0)
- {
- l = bin(cur,tx[i].l);
- r = bin(cur,tx[i].r)-1;
- Insert(1,l,r,tx[i].va);
- tans += (ll)tree[1].len*(tx[i+1].high-tx[i].high);
- }
- else
- {
- l = bin(cur,ty[i].l);
- r = bin(cur,ty[i].r)-1;
- if(r < l )continue;
- Insert(1,l,r,ty[i].va);
- tans += (ll)tree[1].len*(ty[i+1].high-ty[i].high);
- }
- //cout << tree[i].len << endl;
- //cout << tans <<endl;
- }
- //cout << tans <<endl;
- return tans;
- }
- int main()
- {
- while(scanf("%I64d%I64d%d%d",&w,&h,&n,&ma) != EOF)
- {
- tox = 0,toy = 0;
- ll x1,y1,x2,y2;
- for(int i = 1; i <= n; i++)
- {
- scanf("%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2);
- x2++,y2++;
- ll t1 = (x2+ma-1)>w+1? w+1:x2+ma-1;
- tx[tox].l = x1,tx[tox].r = t1,tx[tox].high = y1,tx[tox].va = 1;
- hs[0][tox++] = x1;
- tx[tox].l = x1,tx[tox].r = t1,tx[tox].high = y2,tx[tox].va = -1;
- hs[0][tox++] = t1;
- t1 = (y2+ma-1)>h+1? h+1:y2+ma-1;
- ty[toy].l = y1,ty[toy].r = t1,ty[toy].high = x1,ty[toy].va = 1;
- hs[1][toy++] = y1;
- ty[toy].l = y1,ty[toy].r = t1,ty[toy].high = x2,ty[toy].va = -1;
- hs[1][toy++] = t1;
- }
- if(ma != 1){
- tx[tox].l = 1,tx[tox].r = ma,ty[toy].l=1,ty[toy].r = ma;
- tx[tox].high=1,tx[tox].va=1,ty[toy].high=1,ty[toy].va=1;
- hs[0][tox++] = 1,hs[1][toy++]=1;
- tx[tox].l = 1,tx[tox].r = ma,ty[toy].l=1,ty[toy].r = ma;
- tx[tox].high=h+1,tx[tox].va=-1,ty[toy].high=w+1,ty[toy].va=-1;
- hs[0][tox++] = ma,hs[1][toy++] = ma;
- }
- sort(hs[0],hs[0]+tox);
- sort(hs[1],hs[1]+toy);
- sort(tx,tx+tox,cmp);
- sort(ty,ty+toy,cmp);
- ll ans = w*h*2;
- ans -= solve(0);
- //printf("%I64d\n",ans);
- ans -= solve(1);
- if(ma == 1)
- ans /= 2;
- printf("%I64d\n",ans);
- }
- return 0;
- }
- */
hdu 4052 线段树扫描线、奇特处理的更多相关文章
- hdu 1828 线段树扫描线(周长)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- hdu 5091(线段树+扫描线)
上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...
- HDU 5107 线段树扫描线
给出N个点(x,y).每一个点有一个高度h 给出M次询问.问在(x,y)范围内第k小的高度是多少,没有输出-1 (k<=10) 线段树扫描线 首先离散化Y坐标,以Y坐标建立线段树 对全部的点和询 ...
- hdu 1255(线段树 扫描线) 覆盖的面积
http://acm.hdu.edu.cn/showproblem.php?pid=1255 典型线段树辅助扫描线,顾名思义扫描线就是相当于yy出一条直线从左到右(也可以从上到下)扫描过去,此时先将所 ...
- HDU 5091 线段树扫描线
给出N个点.和一个w*h的矩形 给出N个点的坐标,求该矩形最多能够覆盖多少个点 对每一个点point(x.y)右边生成相应的点(x+w,y)值为-1: 纵向建立线段树,从左到右扫描线扫一遍.遇到点则用 ...
- hdu 1542 线段树+扫描线 学习
学习扫描线ing... 玄学的东西... 扫描线其实就是用一条假想的线去扫描一堆矩形,借以求出他们的面积或周长(这一篇是面积,下一篇是周长) 扫描线求面积的主要思想就是对一个二维的矩形的某一维上建立一 ...
- hdu 4419 线段树 扫描线 离散化 矩形面积
//离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...
- hdu 3265 线段树扫描线(拆分矩形)
题意: 给你n个矩形,每个矩形上都有一个矩形的空洞,所有的矩形都是平行于x,y轴的,最后问所有矩形的覆盖面积是多少. 思路: 是典型的矩形覆盖问题,只不过每个矩形上多了一个矩 ...
- HDU 1828 线段树+扫描线(计算矩形周长并)
题意:给你n个矩形,然后矩形有可能重叠,要你求周长 思路:首先碰到这种矩形在数轴上那么第一反应应该想到的是扫描线, 做周长我们有两种方法 第一种,我们可以分开两部分求,第一遍求x轴上的贡献,第二遍求y ...
随机推荐
- python的迭代器、生成器、装饰器
迭代器.生成器.装饰器 在这个实验里我们学习迭代器.生成器.装饰器有关知识. 知识点 迭代器 生成器 生成器表达式 闭包 装饰器 实验步骤 1. 迭代器 Python 迭代器(Iterators)对象 ...
- 使用SecureCRTP 连接生产环境的web服务器和数据库服务器
一.使用SecureCRTP 连接生产环境的web服务器 首先,需要知道以下参数信息: 1.web服务器的ip地址 2.服务器的端口号 3.会话连接的用户名和密码 4.服务器的用户名 ...
- mysql命令行大全
1.连接Mysql 格式: mysql -h主机地址 -u用户名 -p用户密码1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root ...
- git cherry-pick 整理
git cherry-pick可以选择某一个分支中的一个或几个commit(s)来进行操作.例如,假设我们有个稳定版本的分支,叫v2.0,另外还有个开发版本的分支v3.0,我们不能直接把两个分支合并, ...
- 【漏洞复现】PHPCMS wap模块 SQL注入(附EXP)
漏洞影响版本:v9.5.8.v9.6.0 Step1: 访问:http://www.xxx.com/index.php?m=wap&a=index&siteid=1, 获取返回的coo ...
- 新概念英语(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 ...
- css(1-1)样式表
CSS Id 和 Class id 和 class 选择器 如果你要在HTML元素中设置CSS样式,你需要在元素中设置"id" 和 "class"选择器. id ...
- PL/SQL Developer 导入导出操作
一.PL/SQL Developer数据导入 Tools->Import Tables
- git初试
在gitLab上新建一个项目,creat项目文件之后,进入到项目的路径之后,复制命令git clone ‘git@gitlab.touzila.com:xiacaixiang/gitgitTest1. ...
- Java-NIO(四):通道(Channel)的原理与获取
通道(Channel): 由java.nio.channels包定义的,Channel表示IO源与目标打开的连接,Channel类似于传统的“流”,只不过Channel本身不能直接访问数据,Chann ...