2020ICPC·小米 网络选拔赛第一场 J - Matrix Subtraction(差分 + 树状数组)

链接:https://ac.nowcoder.com/acm/contest/7501/J
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

Given a matrix MM_{}M​ of size n×mn\times mn×m and two integers a,ba, b_{}a,b​, determine weither it is possible to make all entrys of MM_{}M​ zero by repeatedly choosing a×ba\times ba×b submatrices and reduce the values in the chosen matrices by 1. If possible, print "^_^" in one line, or print "QAQ" in one line.

输入描述:

The first line contains one integer T (1≤T≤100), denoting the number of test cases.

For each test case:

The first line contains four integers n,m,a,b (1≤n,m≤1000,1≤a≤n,1≤b≤m)n,m,a,b~(1\le n,m \le 1000, 1\le a\le n, 1\le b\le m)n,m,a,b (1≤n,m≤1000,1≤a≤n,1≤b≤m), denoting the size of given matrix and the size of chosen submatrices respectively.

The next nn_{}n​ lines each contains mm_{}m​ integers Mi,j (0≤Mi,j≤109)M_{i,j}~(0\le M_{i,j} \le 10^9)Mi,j​ (0≤Mi,j​≤109), denoting the entrys of matrix MM_{}M​.

It's guaranteed that ∑nm≤106\sum nm \le 10^6∑nm≤106.

输出描述:

Print TT_{}T​ lines each containing a string "^_^" or "QAQ", denoting the answer to each test case.

示例1

输入

2
2 2 1 2
1 2
1 2
2 3 1 2
1 2 1
1 2 1

输出

QAQ
^_^

说明

For the second case, one possible scheme is to choose (1,1)−(1,2),(1,2)−(1,3),(2,1)−(2,2),(2,2)−(2,3)respectively.

题意:

有一个矩阵,每次可以选择一个大小为a * b的子矩阵,把子矩阵中的每个数减1,问若干操作后原矩阵是否可以都减为0

从左上角开始减,使用树状数组的区间修改和单点查询。

(今天下午为什么没AC:数组开大了导致memset超时

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e3 + 20;
ll mp[N][N];
ll aa[N][N];
ll n, m, a, b, nn;

ll lowbit(ll k) {
    return k & (-k);
}

void add(ll x, ll y, ll v) {
    while(x <= nn) {        ///nn需要修改
        ll ty = y;
        while(ty <= nn)     ///nn需要修改
            mp[x][ty] += v, ty += lowbit(ty);
        x += lowbit(x);
    }
}

void real_add(ll x1, ll y1, ll x2, ll y2, ll v) {
    add(x1, y1, v);
    add(x1, y2 + 1, -v);
    add(x2 + 1, y1, -v);
    add(x2 + 1, y2 + 1, v);
}

ll sum(ll x, ll y) {
    ll res = 0;
    while(x) {
        ll ty = y;
        while(ty)
            res += mp[x][ty], ty -= lowbit(ty);
        x -= lowbit(x);
    }
    return res;
}

int main() {
    ll t;
    scanf("%lld", &t);
    while(t--) {
        scanf("%lld%lld%lld%lld", &n, &m, &a, &b);
        memset(mp, 0, sizeof(mp));
        nn = max(n, m);
        for(ll i = 1; i <= n; i++) {
            for(ll j = 1; j <= m; j++) {
                scanf("%lld", &aa[i][j]);
                add(i, j, aa[i][j] - aa[i][j - 1] - aa[i - 1][j] + aa[i - 1][j - 1]);
            }
        }
        bool flag = 1;
        for(ll k = 2; k <= n + m; ++k) {
            for(ll i = 1; i < k; ++i) {
                ll x1 = i, y1 = k - i;
                ll x2 = x1 + a - 1, y2 = y1 + b - 1;
                if(x1 < 1 || x1 > n || y1 < 1 || y1 > m) continue;
                if(x2 < 1 || x2 > n || y2 < 1 || y2 > m) continue;
                ll tmp = sum(x1, y1);
                if(tmp < 0) {
                    flag = 0;
                    break;
                }
                else if(tmp > 0) real_add(x1, y1, x2, y2, -tmp);
            }
            if(!flag) break;
        }
        if(flag) {
            for(ll i = 1; i <= n; ++i) {
                for(ll j = 1; j <= m; ++j) {
                    if(sum(i, j) != 0) {
                        flag = 0;
                        break;
                    }
                }
                if(!flag) break;
            }
        }
        if(flag) printf("^_^\n");
        else printf("QAQ\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43871207/article/details/109278038