求助卡常
查看原帖
求助卡常
204109
Daniel1234楼主2023/11/23 22:03
#include<bits/stdc++.h>
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline int getc(){
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;
}
inline int read() {
    int ret = 0,f = 0;char ch = getc();
    while (!isdigit (ch)) {
        if (ch == '-') f = 1;
        ch = getc();
    }
    while (isdigit (ch)) {
        ret = ret * 10 + ch - 48;
        ch = getc();
    }
    return f?-ret:ret;
}
const int B = 36;
int n, q;
int a[501][501];
vector<int>t[501][501], h[501][501];
bitset<B*B+1>bb[4];
int tt[4][B*B+1];
int lowbit(int x){
    return x & (-x);
}
int p[500];
int ord[250001];
int len;
int tong[250001];
bitset<250001>bit;
int kk[250001];
int k_[250001];
void pai(vector<int> &g){
    int len = g.size();
    for(int i = 1; i <= len; i++)kk[i] = g[i-1];
    memset(p, 0, sizeof(p));
    for(int i = 1; i <= len; ++i)p[kk[i]%500]++;
    for(int i = 1; i < 500; ++i)p[i] += p[i - 1];
    for(int i = len; i >= 1; i--)k_[p[kk[i]%500]--] = kk[i]; 
    memset(p, 0, sizeof(p));
    for(int i = 1; i <= len; ++i)p[k_[i]/500]++;
    for(int i = 1; i < 500; ++i)p[i] += p[i - 1];
    for(int i = len; i >= 1; i--)kk[p[k_[i]/500]--] = k_[i];
    for(int i = 0; i < len; i++)g[i] = kk[i+1];
}
int s[4][B*B+1];
int cnt[4];
void solve(int op, int x, int y){
    if(x%B==0||y%B==0)return;
    for(int i = x/B*B+1; i <= x; ++i){
        for(int j = y/B*B+1; j <= y; ++j){
            s[op][++cnt[op]] = a[i][j];
        }
    }
    memset(p, 0, sizeof(p));
    for(int i = 1; i <= cnt[op]; ++i)p[s[op][i]%500]++;
    for(int i = 1; i < 500; ++i)p[i] += p[i - 1];
    for(int i = cnt[op]; i >= 1; i--)k_[p[s[op][i]%500]--] = s[op][i]; 
    memset(p, 0, sizeof(p));
    for(int i = 1; i <= cnt[op]; ++i)p[k_[i]/500]++;
    for(int i = 1; i < 500; ++i)p[i] += p[i - 1];
    for(int i = cnt[op]; i >= 1; i--)s[op][p[k_[i]/500]--] = k_[i];
}
int mx;
int find(int op){
    int l = 1, r = cnt[op], ans = 0;
    while(l <= r){
        int mid = l+r>>1;
        if(s[op][mid] <= mx)ans = mid, l = mid + 1;
        else r = mid - 1;
    }
    return ans;
}
int get_t(int x, int y){
    int len = t[x][y].size();
    if(!len)return 0;
    if(t[x][y][len - 1] <= mx)return len;
    int ans = upper_bound(t[x][y].begin(), t[x][y].end(), mx) - t[x][y].begin();
    return ans;
}
int get_h(int x, int y){
    int len = h[x][y].size();
    if(!len)return 0;
    if(h[x][y][len - 1] <= mx)return len;
    int ans = upper_bound(h[x][y].begin(), h[x][y].end(), mx) - h[x][y].begin();
    return ans;
}
int get(int x, int y){
    int ans = get_t(x/B*B, y/B*B);
    if(x % B != 0){
        int nowy = y / B;
        while(nowy){
            ans += get_h(x, nowy*B);
            nowy -= lowbit(nowy);
        }
    }
    if(y % B != 0){
        int nowx = x / B;
        while(nowx){
            ans += get_h(nowx*B, y);
            nowx -= lowbit(nowx);
        }
    }
    return ans;
}
int check(int x, int y, int x_, int y_, int mm){
    mx = mm;
    int ans = find(0) + find(1) - find(2) - find(3);
    ans += get(x_, y_);
    ans -= get(x_, y - 1);
    ans -= get(x - 1, y_);
    ans += get(x - 1, y - 1);
    return ans;
}
signed main(){
    cin >> n >> q;
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= n; ++j){
            a[i][j]=read();
            ord[++len]=a[i][j];
        }
    }
    sort(ord+1,ord+1+len);
    int len_ = len;
    len = 0;
    for(int i = 1; i <= len_; ++i){
        if(i == 1 || ord[i] != ord[i - 1]){
            ord[++len] = ord[i];
        }
    }
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= n; ++j){
            a[i][j] = lower_bound(ord+1, ord+1+len, a[i][j])-ord;
        }
    }
    for(int i = B; i <= n; i += B){
        for(int j = B; j <= n; j += B){
            t[i][j].resize(i*j);
            int now=0;
            for(int x = 1; x <= i; ++x){
                for(int y = 1; y <= j; ++y){
                    tong[a[x][y]]++;
                    bit[a[x][y]] = 1;
                }
            }
            for(int k = bit._Find_first(); k != bit.size(); k = bit._Find_next(k)){
                while(tong[k]--){
                    t[i][j][now++] = k;
                }
                bit[k] = 0;
                tong[k]++;
            }
        }
    }
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= n; ++j){
            if(i % B == 0 && j % B != 0){
                int preij = i - lowbit(i/B)*B;
                h[i][j].resize((i-preij)*(j-j/B*B));
                int now=0;
                for(int x = preij + 1; x <= i; ++x){
                    for(int y = j / B * B + 1; y <= j; ++y){
                        h[i][j][now++] = a[x][y];
                    }
                }
                pai(h[i][j]);
            }
            if(i % B != 0 && j % B == 0){
                int preij = j - lowbit(j/B)*B;
                h[i][j].resize((j-preij)*(i-i/B*B));
                int now=0;
                for(int x = i / B * B + 1; x <= i; ++x){
                    for(int y = j - lowbit(j/B)*B + 1; y <= j; ++y){
                        h[i][j][now++] = a[x][y];
                    }
                }
                pai(h[i][j]);
            }
        }
    }
    while(q--){
        int x, y, x_, y_, k;
        x=read();
        y=read();
        x_=read();
        y_=read();
        k=read();
        cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
        solve(0, x_, y_);
        solve(1, x - 1, y - 1);
        solve(2, x_, y - 1);
        solve(3, x - 1, y_);
        int l = 1, r = len, ans;
        while(l <= r){
            int mid = l+r>>1;
            if(check(x, y, x_, y_, mid) >= k){
                ans = mid;
                r = mid - 1;
            }else{
                l = mid + 1;
            }
        }
        printf("%d\n", ord[ans]);
    }
    return 0;
}

RT,还差0.1s

2023/11/23 22:03
加载中...