【cdoj 1071】秋实大哥下棋 扫描线+线段树+脑洞
来源:互联网 发布:清新博客程序源码 编辑:程序博客网 时间:2024/05/17 07:32
首先,我们注意到就是题目中所说的,只有在矩形内部的车才能够保护矩形内部的各个点,这就说明,我们需要在进入矩阵和离开矩阵的时候要分别判断,而这就是一个相当大的扫描线的提示。
先分析一边的情况,我们以x坐标从左到右开始扫,如果一个矩形能够被车保护,那么他的右边到左边之间的所有车能够把这个矩阵的上边到下边之间的纵坐标全部覆盖完,也就是说现在需要处理两个东西,一个是是否覆盖完,一个是覆盖完所用的车中的最小横纵标(如果连最小横坐标都大于它的左边,那么所用的车一定在左右边之间),而这些东西都可以用一颗线段树全部解决,线段树直接维护扫描线上的最小横坐标,如果没有覆盖,最小横坐标小于矩阵左边横坐标
那么也有可能是上下啊,没关系,把所有横纵坐标swap一次,再原封不动的做一次就过了。
注意,swap后重新排序,一开始我忘了wa了一次还是第一组
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define maxn 100006*2#define ls u<<1,l,mid#define rs u<<1|1,mid+1,rusing namespace std;int n,m,k,q,vis[maxn],cnt,mx,my;struct CAR{int x,y;bool operator <(const CAR& b)const{return x==b.x?y>b.y:x<b.x;}}car[maxn];struct edge{int rx,ry,id,lx,ly;bool operator<(const edge& b)const{return rx==b.rx?ry>b.ry:rx<b.rx;}}e[maxn];struct node{int l,r,Min;}nod[100005*4];void push_up(int u){nod[u].Min=min(nod[u<<1].Min,nod[u<<1|1].Min);}void build(int u,int l,int r){nod[u].l=l,nod[u].r=r;if(l==r){nod[u].Min=-1;return;}int mid=l+r>>1;build(ls);build(rs);push_up(u);}void updata(int u,int l,int r,int x,int add){if(l==r){nod[u].Min=add;return ;}int mid=l+r>>1;if(x>mid)updata(rs,x,add);else updata(ls,x,add);push_up(u);}int query(int u,int l,int r,int x,int y){if(x==l&&r==y)return nod[u].Min;int mid=l+r>>1;if(x>mid)return query(rs,x,y);else if(y<=mid)return query(ls,x,y);else return min(query(ls,x,mid),query(rs,mid+1,y));}void find(){int pre=1;build(1,1,mx);for(int i=1;i<=q;i++){while(car[pre].x<=e[i].rx&&pre<=k){updata(1,1,mx,car[pre].y,car[pre].x);pre++;}int Min=query(1,1,mx,e[i].ly,e[i].ry);if(Min>=e[i].lx)vis[e[i].id]=1;}}int main(){scanf("%d%d%d%d",&n,&m,&k,&q);for(int i=1;i<=k;i++){scanf("%d%d",&car[i].x,&car[i].y);mx=max(max(mx,car[i].x),car[i].y);}for(int i=1;i<=q;i++){scanf("%d%d%d%d",&e[i].lx,&e[i].ly,&e[i].rx,&e[i].ry);mx=max(mx,max(e[i].lx,e[i].ly));mx=max(mx,max(e[i].rx,e[i].ry));e[i].id=i;}mx=100000;sort(car+1,car+1+k);sort(e+1,e+1+q);find();for(int i=1;i<=k;i++)swap(car[i].x,car[i].y);for(int i=1;i<=q;i++)swap(e[i].lx,e[i].ly),swap(e[i].rx,e[i].ry);sort(car+1,car+1+k);sort(e+1,e+1+q);find();for(int i=1;i<=q;i++){if(vis[i])printf("YES\n");else printf("NO\n");}return 0;}
0 0
- 【cdoj 1071】秋实大哥下棋 扫描线+线段树+脑洞
- CDOJ 1071 秋实大哥下棋
- CDOJ 1058 秋实大哥与家 线段树+扫描线
- cdoj 2015数据结构专题:M - 秋实大哥与线段树
- CDOJ-1057 秋实大哥与花(线段树区间更新)
- cdoj 1061 秋实大哥与战争 线段树,合并区间,单点更新,单点查询区间长度
- CDOJ 1060 秋实大哥与快餐店 字典树
- CDOJ 1057 秋实大哥与花 裸线段树
- CDOJ 1070 秋实大哥打游戏
- 2015 UESTC Training for Data Structures 秋实大哥下棋
- 秋实大哥与线段树 UESTC
- cdoj 2015数据结构专题:B - 秋实大哥与花
- cdoj 2015数据结构专题:C - 秋实大哥与快餐店
- cdoj 2015数据结构专题:D - 秋实大哥与战争
- cdoj 2015数据结构专题:G - 秋实大哥去打工
- cdoj 2015数据结构专题:H - 秋实大哥打游戏
- cdoj 2015数据结构专题:N - 秋实大哥搞算数
- CDOJ 1059 秋实大哥与小朋友(离散化)
- Think in java中的final
- Codeforces Problem 710A King Moves(implementation)
- 浅谈Code Review
- 记一次应用启动bug
- 9. Palindrome Number
- 【cdoj 1071】秋实大哥下棋 扫描线+线段树+脑洞
- 回溯——八皇后问题
- 图片上传通过Bitmap转换成Base64编码然后当做请求参数上传
- 线性表-顺序存储结构
- Android中保存文件到指定路径下
- 你交给某人一个程序,你将折磨他一整天,如果你教某人如何编写程序,你将折磨一辈子。
- 数据结构实验之数组三:快速转置
- 【cdoj 843】冰雪奇缘 线段树保留区间
- 计蒜客 18题 跳跃游戏