大佬求助,整体二分

P1527 [国家集训队] 矩阵乘法

Xiongzx @ 2023-03-21 20:47:51

#include <bits/stdc++.h>

#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define pre(i, a, b) for(int i = (a); i >= (b); i--)
#define Ede(i, u) for(int i = h[u]; i; i = ne[i])
#define go(i, a) for(auto i : a)
//#define int long long
#define LL long long
#define ULL unsigned long long
#define PII pair<int, int>
#define PIL pair<int, long long>
#define PLI pair<long long, int>
#define PLL pair<long long, long long>
#define mp make_pair
#define eb emplace_back
#define pb push_back
#define pf push_front
#define fi first
#define se second
#define sf scanf
#define prf printf
#define el putchar('\n')
#define mms(arr, n) memset(arr, n, sizeof(arr))
#define mmc(arr1, arr2) memcpy(arr1, arr2, sizeof(arr2))
const int inf = 0x3f3f3f3f;

template <typename T> inline void rd(T &x){
    x = 0; bool f = true; char ch = getchar();
    while(ch < '0' || ch > '9'){ if(ch == '-') f = false; ch = getchar();}
    while(ch >= '0' && ch <= '9'){ x = (x << 1) + (x << 3) + (ch ^ '0'); ch = getchar();}
    if(!f) x = -x;
}
template <typename T, typename ...Args> inline void rd(T &x, Args &...args){ rd(x); rd(args...);}

using namespace std;

const int N = 510, M = 3.5e5;
struct Node{
    int ins;
    int r, c, x;
    int r1, c1, r2, c2, k, id;
}q[M], lq[M], rq[M];
int n, qq, ans[M]; 

int ta[N][N];
int lowbit(int x){ return x & -x;} 
void add(int x, int y0, int a){
    for(; x <= n; x += lowbit(x)){
        for(int y = y0; y <= n; y += lowbit(y)){
            ta[x][y] += a;
        }
    }
} 
int query(int x, int y0){
    int sum = 0;
    for(; x; x -= lowbit(x)){
        for(int y = y0; y; y -= lowbit(y)){
            sum += ta[x][y];
        }
    }
    return sum;
}

void solve(int vl, int vr, int ql, int qr){
    if(ql > qr) return;
    if(vl = vr){
        rep(i, ql, qr) if(q[i].ins == 2) ans[q[i].id] = vl;
        return;
    }

    int mid = (vl + vr) >> 1;
    int nl = 0, nr = 0;
    rep(i, ql, qr){
        if(q[i].ins == 1){
            if(q[i].x <= mid){
                add(q[i].r, q[i].c, 1);
                lq[++nl] = q[i];
            }else rq[++nr] = q[i];
        }else{
            int sum = query(q[i].r2, q[i].c2) - query(q[i].r2, q[i].c1 - 1) - query(q[i].r1 - 1, q[i].c2) + query(q[i].r1 - 1, q[i].c1 - 1);
            if(sum >= q[i].k) lq[++nl] = q[i];
            else{
                q[i].k -= sum;
                rq[++nr] = q[i];
            }
        }
    }

    rep(i, ql, qr){
        if(q[i].ins == 1){
            if(q[i].x <= mid){
                add(q[i].r, q[i].c, -1);
            }
        }
    }

    rep(i, 1, nl) q[ql + i - 1] = lq[i];
    rep(i, 1, nr) q[ql + nl + i - 1] = rq[i];
    solve(vl, mid, ql, ql + nl - 1);
    solve(mid + 1, vr, ql + nl, qr);
}

int main(){
    /*
    freopen(".in", "r", stdin);
    freopen(".out", "w", stdout);
    */
    rd(n, qq);
    int cnt = 0, mi = 1e9, ma = -1;
    rep(i, 1, n){
        rep(j, 1, n){
            rd(q[++cnt].x);
            mi = min(mi, q[cnt].x), ma = max(ma, q[cnt].x);
            q[cnt].ins = 1;
            q[cnt].r = i, q[cnt].c = j;
        }
    }
    rep(i, 1, qq){
        q[++cnt].ins = 2;
        q[cnt].id = cnt;
        rd(q[cnt].r1, q[cnt].c1, q[cnt].r2, q[cnt].c2, q[cnt].k);
    }

    solve(mi, ma, 1, cnt);

    cnt = n * n;
    rep(i, 1, qq) prf("%d\n", ans[cnt + i]);
    return 0;
}

by tjx114514 @ 2024-05-06 15:46:43

@lao_wang


|