CDOJ 1071 秋实大哥下棋
来源:互联网 发布:能听着背单词的软件 编辑:程序博客网 时间:2024/06/10 09:43
秋实大哥下棋
limit 1s 65535KB
胜负胸中料已明,又从堂上出奇兵。秋实大哥是一个下棋好手,独孤求败的他觉得下棋已经无法满足他了,他开始研究一种新的玩法。
在一个n×m的棋盘上,放置了k个车,并且他在棋盘上标出了q个矩形,表示矩形内部是战略要地。秋实大哥要求一个矩形内的每一个格子,都至少能被一辆在矩形内的车攻击到,那么这个矩形就是被完整保护的。
现在秋实大哥想知道每一个矩形是否被完整保护。
input
第一行包含四个整数n,m,k,q,表示棋盘的大小,车的数量以及矩形的数量。
接来下k行,每行包含两个整数x,y,表示有一辆车位于从左往右第x列,从下往上第y行。
接下来q行,每行包含四个整数x1,y1,x2,y2,表示一个矩形的左下角和右上角坐标。
1≤n,m≤105,1≤k,q≤2⋅105,1≤x1≤x2≤105,1≤y1≤y2≤105,1≤x≤105,1≤y≤105。
output
输出q行,对于每一次询问,这个矩形若被完整保护了输出"YES",否则输出"NO"。
sameple input
4 3 3 31 13 22 32 3 2 32 1 3 31 2 2 3sameple output
YES
YES
NO
题解
好难啊,完全不会
所以看题解,问大神,折腾了好久终于敢自己写一发了……
竟然一发过,开心……
但是题解很不好表述啊,怎么说,X,Y分开进行,比如X轴方向扫描,在Y轴上建线段树,线段树维护[y1,y2]区间内车的X的最小值。
每次扫描到一个矩形的右边,就询问[y1,y2]区间中车的X的最小值,如果X小于该矩形的左边,说明纵坐标在[Y1,Y2]区间的车至少一辆不在矩形内,覆盖失败
Y轴一样
#include<bits/stdc++.h>#include<vector>using namespace std;const int maxn=1e5;const int max_size=1<<18;const int inf=1e7;struct Carriage{int x;int y;};Carriage car[2*maxn+5];struct Retangular{int x1,x2,y1,y2;};Retangular ret[2*maxn+5];vector <int> x_car[maxn+5];vector <int> y_car[maxn+5];vector <int> rside[maxn+5];vector <int> hside[maxn+5];int x_tree[max_size+5];int y_tree[max_size+5];int ans[2*maxn+5];void update(int tree[],int x,int m,int sz){x+=sz-1;tree[x]=m;x>>=1;while (x>=1){tree[x]=min(tree[x<<1],tree[(x<<1)+1]);x>>=1;}}int query(int tree[],int a,int b,int k,int l,int r){if (a<=l && r<=b) return tree[k];else if (r<a || b<l) return inf;else{int mid=(l+r)/2;return min(query(tree,a,b,k<<1,l,mid),query(tree,a,b,(k<<1)+1,mid+1,r));}}void y_solve(int n,int sz_y){for (int i=1;i<=n;++i){if (!x_car[i].empty()){for (int j=0;j<x_car[i].size();++j){int t=x_car[i][j];update(y_tree,car[t].y,car[t].x,sz_y);}}if (!rside[i].empty()){for (int j=0;j<rside[i].size();++j){int t=rside[i][j];if (query(y_tree,ret[t].y1,ret[t].y2,1,1,sz_y)<ret[t].x1) {ans[t]+=1;}}}}}void x_solve(int m,int sz_x){for (int i=1;i<=m;++i){if (!y_car[i].empty()){for (int j=0;j<y_car[i].size();++j){int t=y_car[i][j];update(x_tree,car[t].x,car[t].y,sz_x);}}if (!hside[i].empty()){for (int j=0;j<hside[i].size();++j){int t=hside[i][j];if (query(x_tree,ret[t].x1,ret[t].x2,1,1,sz_x)<ret[t].y1) {ans[t]+=1;}}}}} int main(void){#ifdef exfreopen ("in.txt","r",stdin);#endifint n,m,k,q;int x,y,x1,x2,y1,y2;scanf("%d%d%d%d",&n,&m,&k,&q);int sz_x=1;while (sz_x<n) sz_x<<=1;int sz_y=1;while (sz_y<m) sz_y<<=1;for (int i=1;i<=k;++i){scanf("%d%d",&x,&y);car[i].x=x;car[i].y=y;x_car[x].push_back(i);y_car[y].push_back(i);}for (int i=1;i<=q;++i){scanf("%d%d%d%d",&x1,&y1,&x2,&y2);ret[i].x1=x1;ret[i].x2=x2;ret[i].y1=y1;ret[i].y2=y2;rside[x2].push_back(i);hside[y2].push_back(i);}#ifdef ex1if (x_solve(m,sz_x) && y_solve(n,sz_y)){printf("YES\n");}else{printf("NO\n");}#endifx_solve(m,sz_x);y_solve(n,sz_y);for (int i=1;i<=q;++i){if (ans[i]==2) printf("NO\n");else{printf("YES\n");}}}
0 0
- CDOJ 1071 秋实大哥下棋
- 【cdoj 1071】秋实大哥下棋 扫描线+线段树+脑洞
- CDOJ 1070 秋实大哥打游戏
- 2015 UESTC Training for Data Structures 秋实大哥下棋
- cdoj 2015数据结构专题:B - 秋实大哥与花
- cdoj 2015数据结构专题:C - 秋实大哥与快餐店
- cdoj 2015数据结构专题:D - 秋实大哥与战争
- cdoj 2015数据结构专题:G - 秋实大哥去打工
- cdoj 2015数据结构专题:H - 秋实大哥打游戏
- cdoj 2015数据结构专题:N - 秋实大哥搞算数
- CDOJ 1059 秋实大哥与小朋友(离散化)
- CDOJ 1061 秋实大哥与战争 暴力/set
- CDOJ 1060 秋实大哥与快餐店 字典树
- CDOJ 1057 秋实大哥与花 裸线段树
- CDOJ 1091 秋实大哥の恋爱物语 KMP
- 【CDOJ 1074】秋实大哥搞算术【栈计算表达式】
- CDOJ 1146 秋实大哥与连锁快餐店
- cdoj 2015数据结构专题:F - 秋实大哥与妹纸
- ehcache memcache redis三大缓存男高音
- AndroidStudio项目提交(更新)到github最详细步骤
- hdu 5651 (组合数学 + 阶乘求逆元)
- uestc1134男神的约会【状压dp】
- 判断是不是胖子
- CDOJ 1071 秋实大哥下棋
- 【09类和模块】——5:构造函数名称
- MySQL 入门(二)—— MySQL理论基础
- 字节序(Endianness)
- 自学计算机科学CS总结-by 要有光LTBL
- 04-树6 Complete Binary Search Tree (30分)
- [BZOJ1066]蜥蜴 做题笔记
- JAVAEE 框架 2016-3-28
- OpenStack培训的用户体验