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 ...
随机推荐
- 学生ID查询
var http = require("http"); var server = http.createServer(function(req,res){ //得到url var ...
- 新手入门 git
Git是目前世界上最先进的分布式版本控制系统 特点:高端大气上档次 什么是版本控制系统 系统自动记录文件改动 方便同事协作管理 不用自己管理一堆类似的文件了,也不需要把文件传来传去.如果想查看某次改动 ...
- php的函数参数按照从左到右来赋值
PHP 中自定义函数参数赋默认值 2012-07-07 13:23:00| 分类: php自定义函数,默|举报|字号 订阅 下载LOFTER我的照片书 | php自定义函数接受参数 ...
- 第三章Hibernate关联映射
第三章Hibernate关联映射 一.关联关系 类与类之间最普通的关系就是关联关系,而且关联是有方向的. 以部门和员工为列,一个部门下有多个员工,而一个员工只能属于一个部门,从员工到部门就是多对一关联 ...
- Groovy入门(2-2)Groovy的eclipse插件安装
1.安装eclipse插件 启动eclipse,点击help -> Install New Software... 在弹出的窗口中点击:Add... Groovy插件的地址:http://dis ...
- Spring Security入门(3-4)Spring Security 异常处理、异常传递和异常获取
- js jquery 获取元素(父节点,子节点,兄弟节点),元素筛选
转载:https://www.cnblogs.com/ooo0/p/6278102.html js jquery 获取元素(父节点,子节点,兄弟节点) 一,js 获取元素(父节点,子节点,兄弟节点) ...
- ASP.NET CORE系列【三】使用Entity Framework Core进行增删改查
身份验证 以前我们熟悉的web.config中配置的form验证,现在没有了.我们来看看在Core里面如何配置: 首先需要NuGet安装一个包:Microsoft.AspNetCore.Authent ...
- Spring Boot面试题
Spring Boot 是微服务中最好的 Java 框架. 我们建议你能够成为一名 Spring Boot 的专家. 问题一 Spring Boot.Spring MVC 和 Spring 有什么区别 ...
- __dict__
类有一个__dict__字典属性,保存了当前类的每一个成员,举例如下: >>> class A: def __init__(self,value): self.value=value ...