Conturbatio
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Problem Description
There are many rook on a chessboard, a rook can attack the row and column it belongs, including its own place.
There are also many queries, each query gives a rectangle on the chess board, and asks whether every grid in the rectangle will be attacked by any rook?
There are also many queries, each query gives a rectangle on the chess board, and asks whether every grid in the rectangle will be attacked by any rook?
Input
The first line of the input is a integer
T
, meaning that there are
T
test cases.
Every test cases begin with four integers n,m,K,Q .
K is the number of Rook, Q is the number of queries.
Then K lines follow, each contain two integers x,y describing the coordinate of Rook.
Then Q lines follow, each contain four integers x1,y1,x2,y2 describing the left-down and right-up coordinates of query.
1≤n,m,K,Q≤100,000 .
1≤x≤n,1≤y≤m .
1≤x1≤x2≤n,1≤y1≤y2≤m .
Every test cases begin with four integers n,m,K,Q .
K is the number of Rook, Q is the number of queries.
Then K lines follow, each contain two integers x,y describing the coordinate of Rook.
Then Q lines follow, each contain four integers x1,y1,x2,y2 describing the left-down and right-up coordinates of query.
1≤n,m,K,Q≤100,000 .
1≤x≤n,1≤y≤m .
1≤x1≤x2≤n,1≤y1≤y2≤m .
Output
For every query output "Yes" or "No" as mentioned above.
Sample Input
2 2 2 1 2 1 1 1 1 1 2 2 1 2 2 2 2 2 1 1 1 1 2 2 1 2 2
Sample Output
Yes No YesHintHuge input, scanf recommended.
Source
/************************************************************************/
附上该题对应的中文题
Conturbatio
Time Limit: 6000/3000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
在一个n×m的国际象棋棋盘上有很多车(Rook),其中车可以攻击他所属的一行或一列,包括它自己所在的位置。
现在还有很多询问,每次询问给定一个棋盘内部的矩形,问矩形内部的所有格子是否都被车攻击到?
输入描述
输入文件包含多组数据,第一行为数据组数T。 每组数据有4个正整数n,m,K,Q。 K为车的数量,Q为询问的个数。 接下来有K行,每行两个整数x,y , 表示车所在的坐标。 再接下来有Q行,每行4个整数x1,y1,x2,y2,表示询问的矩形的左下角与右上角的坐标。 1≤n,m,K,Q≤100,000. 1≤x≤n,1≤y≤m. 1≤x1≤x2≤n,1≤y1≤y2≤m.
输出描述
对于每组询问,输出Yes或No。
输入样例
2 2 2 1 2 1 1 1 1 1 2 2 1 2 2 2 2 2 1 1 1 1 2 2 1 2 2
输出样例
Yes No Yes
Hint
输入数据过大,建议使用scanf
/****************************************************/
出题人的解题思路:
Conturbatio
可以发现如果一个矩阵被全部攻击到,很显然要么是因为它的每一行都有车,或者每一列都有车。
所以只需要记录一下哪些行和哪些列有车,对于每个询问只需要做一个前缀和就可以知道答案了。
表示默默地将有车的行和列分别标记为0,没有的记为1,然后维护行线段树与列线段树,求区间最值,有1就是1,也就是说车到不了的位置是1
当每一行都有车或每一列都有车时,矩阵就能被车全部攻击到了
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 100005;
const int inf = 1000000000;
const int mod = 2009;
int a[N],b[N];
struct node
{
int l,r,ma;
}tree[N*4],point[N*4];
void build(int l,int r,int p)
{
tree[p].l = l;
tree[p].r = r;
tree[p].ma = -1;
if(l == r)
{
tree[p].ma = a[l];
return;
}
int mid = (l+r)/2;
build(l,mid,p*2);
build(mid+1,r,p*2+1);
tree[p].ma = max(tree[p*2].ma,tree[p*2+1].ma);
}
int query(int x,int y,int p)
{
if(x == tree[p].l && y == tree[p].r)
return tree[p].ma;
int mid = (tree[p].l + tree[p].r)/2;
if(x > mid)
return query(x,y,p*2+1);
else if(y <= mid)
return query(x,y,p*2);
else
return max(query(x,mid,p*2),query(mid+1,y,p*2+1));
}
void build1(int l,int r,int p)
{
point[p].l = l;
point[p].r = r;
point[p].ma = -1;
if(l == r)
{
point[p].ma = b[l];
return;
}
int mid = (l+r)/2;
build1(l,mid,p*2);
build1(mid+1,r,p*2+1);
point[p].ma = max(point[p*2].ma,point[p*2+1].ma);
}
int query1(int x,int y,int p)
{
if(x == point[p].l && y == point[p].r)
return point[p].ma;
int mid = (point[p].l + point[p].r)/2;
if(x > mid)
return query1(x,y,p*2+1);
else if(y <= mid)
return query1(x,y,p*2);
else
return max(query1(x,mid,p*2),query1(mid+1,y,p*2+1));
}
int main()
{
int T,i,j,k,n,m,K,Q,q,x,y,x1,y1,x2,y2;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&n,&m,&K,&Q);
for(i=1;i<=n;i++)
a[i]=1;
for(i=1;i<=m;i++)
b[i]=1;
for(i=0;i<K;i++)
{
scanf("%d%d",&x,&y);
a[x]=0,b[y]=0;
}
/*for(i=1;i<=n;i++)
printf("%d ",a[i]);
puts("#");
for(i=1;i<=m;i++)
printf("%d ",b[i]);
puts("@");*/
build(1,n,1);
build1(1,m,1);
for(i=1;i<=Q;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
//printf("%d %d\n",query(x1,x2,1),query1(y1,y2,1));
if(!query(x1,x2,1)||!query1(y1,y2,1))
puts("Yes");
else
puts("No");
}
}
return 0;
}
菜鸟成长记