HDU 5480 Conturbatio 树状数组

Conturbatio

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 898    Accepted Submission(s): 403


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?
 

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.

1n,m,K,Q100,000 .

1xn,1ym .

1x1x2n,1y1y2m .
 

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 Yes
Hint
Huge input, scanf recommended.
 
这个题是个对树状数组的拓展 挺有意思的 题意就是在一个棋盘中 给你两个点 判断在这两个点所确定的棋盘区域内的车(所在的行和列可以随便跑)的移动范围能否覆盖整个区域
//hdu 5480 Conturbatio 树状数组 
#include <iostream>
#include <cstring>
using namespace std;
const int maxn=100002;
int n;
int a[2][maxn];//定义二维数组代表x轴y轴 
int visx[maxn],visy[maxn];//记录对应的x y 是否已被访问过 

int lowbit(int x)
{
    return x&(-x);
}
int cal(int i,int t)//计算1-t的和
{
    int sum=0;
    while(t>0)
    {
        sum+=a[i][t];
        t-=lowbit(t);
    }
    return sum;
}
void add(int i,int x,int v)//在x的位置加上v
{
    while(x<=n)
    {
        a[i][x]+=v;
        x+=lowbit(x);
    }
}
int main()
{
	ios::sync_with_stdio(false);
	int t;
	int m,k,q;
	int x,y;
	int x1,x2,y1,y2;
	cin>>t;
	while(t--)
	{
		memset(a,0,sizeof(a));
		memset(visx,0,sizeof(visx));
		memset(visy,0,sizeof(visy));
		cin>>n>>m>>k>>q;
		while(k--)
		{
			cin>>x>>y;
			if(visx[x]==0)
			{
				visx[x]=1;
				add(0,x,1);
			}
			if(visy[y]==0)
			{
				visy[y]=1;
				add(1,y,1); 
			}
		}
		while(q--)
		{
			cin>>x1>>y1>>x2>>y2;
			int xma=max(x1,x2);
            int yma=max(y1,y2);
            int xmi=min(x1,x2);
            int ymi=min(y1,y2);
            if((cal(0,xma)-cal(0,xmi-1)==xma-xmi+1)||(cal(1,yma)-cal(1,ymi-1)==yma-ymi+1))
            {
                cout<<"Yes"<<endl;
            }
            else cout<<"No"<<endl;
        }
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值