卡时卡的我心塞啊
因为插入操作太多而且没有顺序我们需要在sort后的插入操作上滚来滚去= =
其实并不需要排序opt数组,而用int下标排序可避免复制的时间过长。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ctime>
#define maxn 510
using namespace std;
void read(int &num){
num = 0;char ch = getchar();
for(;ch < '!'; ch = getchar());
for(;ch > '!'; ch = getchar())
num = num * 10 + ch - 48;
}
int N, Q;
//BIT{
int t[maxn][maxn];
int lowbit[maxn];
#define lowbit_cal(x) (x & ((~x) + 1))
void update(int x, int y, const int& val){
if(!x || !y)return;
int tmp = y;
while(x <= N){
y = tmp;
while(y <= N){
t[x][y] += val;
y += lowbit_cal(y);
}
x += lowbit_cal(x);
}
}
int ask(int x, int y){
if(!x || !y)return 0;
int tmp = y, ans = 0;
while(x){
y = tmp;
while(y){
ans += t[x][y];
y -= lowbit_cal(y);
}
x -= lowbit_cal(x);
}
return ans;
}
int ask(const int& x1, const int& y1, const int& x2, const int& y2){
int ans = ask(x1 - 1, y1 - 1) + ask(x2, y2);
ans -= ask(x2, y1 - 1) + ask(x1 - 1, y2);
return ans;
}
int n;
#define maxq 310010
struct opt{
int x1, y1, tp;
int x2, y2, k;
bool operator<(const opt& k)const{
return tp < k.tp;
}
}q[maxq], q1[maxq], q2[maxq];
const int inf = 0x7fffffff;
int TMP, ans[maxq];
int T = 0;
void solve(int head, int tail, int l, int r){
//cout << head << ' ' << tail << ' ' << l << ' ' << r << endl;
if(head > tail)return;
if(l == r){
for(int i = head; i <= tail; i ++)
ans[q[i].tp] = l;
return;
}
int mid = l + r >> 1;
while(q[T + 1].tp <= mid && T < TMP)
T ++, update(q[T].x1, q[T].y1, 1);
while(q[T].tp > mid && T)
update(q[T].x1, q[T].y1, -1), T --;
int l1 = 0, l2 = 0;
for(int i = head; i <= tail; i ++){
if(ask(q[i].x1, q[i].y1, q[i].x2, q[i].y2) >= q[i].k)
q1[++ l1] = q[i];
else{
//q[i].k -= tmp[i];
q2[++ l2] = q[i];
}
}
int cnt = head;
for(int i = 1; i <= l1; i ++)q[cnt ++] = q1[i];
for(int i = 1; i <= l2; i ++)q[cnt ++] = q2[i];
// memcpy(q + head, q1 + 1, sizeof (q[0]) * l1);
// memcpy(q + head + l1, q2 + 1, sizeof (q[0]) * l2);
solve(head, head + l1 - 1, l, mid);
solve(head + l1, tail, mid + 1, r);
}
int main(){
freopen("nt2012_mat.in","r",stdin);
freopen("nt2012_mat.out","w",stdout);
read(N);
read(Q);
TMP = N * N;
int x;
int mn = inf, mx = -inf;
for(int i = 1; i <= N; i ++){
for(int j = 1; j <= N; j ++){
read(x);
if(x < mn)mn = x;
if(x > mx)mx = x;
++ n;
q[n].x1 = i;
q[n].y1 = j;
q[n].tp = x;
}
}
sort(q + 1, q + 1 + n);
int id = 0;
for(int i = 1; i <= Q; i ++){
++ n;
read(q[n].x1), read(q[n].y1);
read(q[n].x2), read(q[n].y2);
read(q[n].k);
q[n].tp = ++ id;
}
solve(TMP + 1, n, mn, mx);
for(int i = 1; i <= Q; i ++)
printf("%d\n", ans[i]);
return 0;
}