10.28 模拟赛 T4

sporting

题面:

求子矩形绝对众数

\(1\leq n,m \leq 1024,\ 1 \leq a_{i, j} \leq 10^6\)

\(4s,\ 256MB\)


太聪明了,如果一个数是绝对众数,那么它的二进制位在子矩形里也是绝对众数。

于是可以拼二进制位得到可能的答案。

可是这没办法判无解。所以要把答案离线下来再判它到底是不是真的绝对众数,由于答案最多 \(q\) 种,所以复杂度是 \(O((nm + q)\log{V} + (nm + q)\log{m})\)

//        No mind to think.
//
//        No will to break.
//
//        No voice to cry suffering.
//
//        Born of God and Void.
//
//        You shall seal the blinding light that plagues their dreams.
//
//        You are the Vessel.
//
//        You are the Hollow Knight.
#ifdef N2
#define _GLIBCXX_DEBUG
#define LOG(...) fprintf(stderr, __VA_ARGS__)
#else 
#define LOG(...)
#endif
#define syncoff ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1050;
const int maxa = 1145141;
const int maxd = 20;
constexpr inline int bit(int x) {return 1 << x;}
constexpr inline int dig(int x, int d) {return (x >> d) & 1;}
int f[maxn][maxn];
class Query {
public:
    int a, b, c, d;
    int size() {return (c - a + 1) * (d - b + 1);} 
    Query() = default;
    Query(int a, int b, int c, int d) : a(a), b(b), c(c), d(d) {} 
}Q[maxa];
int ans[maxa];
int ext[maxa];
int sum[maxn][maxn];
int a[maxn][maxn];
int n, m, q;
void Count(int d) {
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + dig(a[i][j], d);
        }
    }
    for(int i = 1; i <= q; i++) {
        auto cur = Q[i];
        int c = sum[cur.c][cur.d] - sum[cur.a - 1][cur.d] - sum[cur.c][cur.b - 1] + sum[cur.a - 1][cur.b - 1];
        if(c > cur.size() / 2) ans[i] |= bit(d);
    }
}
class Exist {
public:
    int x, y, opt;
    Exist() = default;
    Exist(int x, int y, int opt) : x(x), y(y), opt(opt) {}
};
vector<Exist> loc[maxa];
class Fenwick {
public:
    int tr[maxn];
    int lowbit(int x) {return x & (-x);}
    void modify(int x, int val, int n) {
        while(x <= n) {
            tr[x] += val;
            x += lowbit(x);
        }
    } 
    int query(int x) {
        int res = 0;
        while(x) {
            res += tr[x];
            x -= lowbit(x);
        }
        return res;
    }
    void clear() {memset(tr, 0, sizeof(tr));}
}fw;
void Check(int val) {
    sort(loc[val].begin(), loc[val].end(), [](Exist a, Exist b) {
        if(a.x != b.x) return a.x < b.x;
        if(a.y != b.y) return a.y < b.y;
        return abs(a.opt) < abs(b.opt);
    });
    fw.clear();
    for(auto cur : loc[val]) {
        if(!cur.opt) fw.modify(cur.y, 1, m);
        else if(cur.opt > 0) ext[cur.opt] += fw.query(cur.y);
        else if(cur.opt < 0) ext[-cur.opt] -= fw.query(cur.y);
    }
}
int main() {
    syncoff;
    cin >> n >> m >> q;
    for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) cin >> a[i][j];
    for(int i = 1; i <= q; i++) cin >> Q[i].a >> Q[i].b >> Q[i].c >> Q[i].d;
    for(int i = 0; i <= maxd; i++) Count(i);
    vector<int> toCheck;
    for(int i = 1; i <= q; i++) {
        toCheck.emplace_back(ans[i]);
        loc[ans[i]].emplace_back(Q[i].c, Q[i].d, i);
        loc[ans[i]].emplace_back(Q[i].a - 1, Q[i].d, -i);
        loc[ans[i]].emplace_back(Q[i].c, Q[i].b - 1, -i);
        loc[ans[i]].emplace_back(Q[i].a - 1, Q[i].b - 1, i);
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= m; j++) {
            loc[a[i][j]].emplace_back(i, j, 0);
        }
    }
    sort(toCheck.begin(), toCheck.end());
    toCheck.resize(unique(toCheck.begin(), toCheck.end()) - toCheck.begin());
    for(int val : toCheck) Check(val);
    for(int i = 1; i <= q; i++) if(ext[i] > Q[i].size() / 2) cout << ans[i] << '\n'; else cout << "-1\n";
}
posted @ 2023-10-28 16:06  N2MENT  阅读(16)  评论(0)    收藏  举报