description整體二分。給你乙個n*n的矩陣,不用算矩陣乘法,但是每次詢問乙個子矩形的第k小數。 input
第一行兩個數n,q,表示矩陣大小和詢問組數; 接下來n行n列一共n*n個數,表示這個矩陣; 再接下來q行每行5個數描述乙個詢問:x1,y1,x2,y2,k表示找到以(x1,y1)為左上角、以(x2,y2)為右下角的子矩形中的第k小數。
output 對於每組詢問輸出第k小的數。
先把矩陣元素排序,定義子問題so
lve(
l,r,
l,r)
表示用[l
,r] 一段元素求解[l
,r] 一段詢問,保證答案就在這個區間。二分答案mi
d ,用二維樹狀陣列可以統計出每個詢問的子矩陣中不超過mi
d 的元素個數。如果不到
k 就分治到右區間【注意這時
k要減去左區間的個數】,否則分治到左區間。
#include
#include
#include
using
namespace
std;
int rd()
return x;
}struct qry
f[60010],g[60010];
struct node
void dec(int x,int y)
int qry(int x,int y)
int query(int x1,int y1,int x2,int y2)
void solve(int l,int r,int l,int r)
int mid=l+r>>1,c1=l,c2=r,x;
for (int i=l;i<=mid;i++) inc(a[i].x,a[i].y);
for (int i=l;i<=r;i++)
}for (int i=l;i<=r;i++) f[i]=g[i];
for (int i=l;i<=mid;i++) dec(a[i].x,a[i].y);
solve(l,mid,l,c2);
solve(mid+1,r,c1,r);
}int main()
sort(a+1,a+m+1);
for (int i=1;i<=q;i++)
solve(1,m,1,q);
for (int i=1;i<=q;i++) ans[f[i].num]=f[i].res;
for (int i=1;i<=q;i++) printf("%d\n",ans[i]);
}
BZOJ 2738 矩陣乘法
卡時卡的我心塞啊 因為插入操作太多而且沒有順序我們需要在sort後的插入操作上滾來滾去 其實並不需要排序opt陣列,而用int下標排序可避免複製的時間過長。include include include include include define maxn 510 using namespace ...
bzoj2738 矩陣乘法
time limit 20 sec memory limit 256 mb submit 1183 solved 504 submit status discuss 給你乙個n n的矩陣,不用算矩陣乘法,但是每次詢問乙個子矩形的第k小數。第一行兩個數n,q,表示矩陣大小和詢問組數 接下來n行n列一共...
bzoj2738 矩陣乘法
m id,每次把權值小於等於mi d 的數對應位置上 1 可以用二維bit實現 然後掃瞄當前的詢問,對於乙個詢問看它對應的那個子矩形中已經插入了幾個數,如果插入的數的個數比詢問的 k 大,就說明列舉的答案過大,就把當前詢問加入左邊,否則加入右邊。然後分治下去。整體二分 二維bit include i...