一.题目链接:

HDU-6514

二.题目大意:

给你 p 个红矩阵

一个整数 q,接下来 q 行

每行给出一个蓝矩阵

如果蓝矩阵被完全包含于红矩阵内,输出 "YES",否则输出 "NO".

三.分析:

赛后听 ltr 讲才恍然大悟,不就是这两道题的结合吗?(tql  orzzzz)

最大子矩阵(HDU - 1559,前缀和)

Color the ball(HDU - 1556,前缀和)

其实就是利用 前缀和处理 + 矩阵和 算出哪些区域是被红矩形标记过的

之后将标记过的点置为 1 ,再来一次前缀和.

之后 O(1) 查询蓝矩阵的子矩阵和即可.

四.代码实现:

#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-6
#define pi acos(-1.0)
#define ll long long int
using namespace std;

const int M = (int)1e7;

vector < vector<int> > mp;
vector < vector<int> > sum;

void init(int n, int m)
{
    mp.clear();
    sum.clear();
    mp.resize(n + 5);
    sum.resize(n + 5);
    for(int i = 0; i < n + 5; ++i)
    {
        mp[i].clear();
        sum[i].clear();
        mp[i].resize(m + 5);
        sum[i].resize(m + 5);
    }
}

void get_sum(int n, int m)
{
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + mp[i][j];
        }
    }
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            if(sum[i][j])
                mp[i][j] = 1;
            else
                mp[i][j] = 0;
            sum[i][j] = 0;
        }
    }
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + mp[i][j];
        }
    }
}

int main()
{
    int n, m;
    while(~scanf("%d %d", &n, &m))
    {
        init(n, m);
        int p;
        scanf("%d", &p);
        while((p--) > 0)
        {
            int x1, y1, x2, y2;
            scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
            swap(x1, x2);
            x1 = n - x1 + 1;
            x2 = n - x2 + 1;
            mp[x1][y1]++;
            mp[x2 + 1][y2 + 1]++;
            mp[x1][y2 + 1]--;
            mp[x2 + 1][y1]--;
        }
        get_sum(n, m);
        int q;
        scanf("%d", &q);
        while((q--) > 0)
        {
            int x1, y1, x2, y2;
            scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
            swap(x1, x2);
            x1 = n - x1 + 1;
            x2 = n - x2 + 1;
            int ans = sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1];
            int area = (x2 - x1 + 1) * (y2 - y1 + 1);
            if(ans == area)
                puts("YES");
            else
                puts("NO");
        }
    }
    return 0;
}