BZOJ2738 矩陣乘法 整體二分 樹狀陣列

2022-08-18 22:27:18 字數 1177 閱讀 9652

給你乙個n*n的矩陣,不用算矩陣乘法,但是每次詢問乙個子矩形的第k小數。

第一行兩個數n,q,表示矩陣大小和詢問組數;

接下來n行n列一共n*n個數,表示這個矩陣;

再接下來q行每行5個數描述乙個詢問:x1,y1,x2,y2,k表示找到以(x1,y1)為左上角、以(x2,y2)為右下角的子矩形中的第k小數。

對於每組詢問輸出第k小的數。

2 22 1

3 41 2 1 2 1

1 1 2 2 313

如果求乙個區間第\(k\)小,可以考慮二分,將\(<=mid\)的值賦成1,用樹狀陣列維護求有多少個數小於等於\(mid\),在和\(k\)進行比較。

如果求乙個矩陣中第\(k\)小,思路同上,這時候可以考慮用二維樹狀陣列進行維護。

那麼求多個矩陣中的,每都一次二分複雜度會炸,所以可以考慮用整體二分√

將當前\(k<=sum\)的放到左區間,\(k>=sum\)的放到右區間繼續二分即可。

#include#define m 505

#define n 60005

#define p 330000

using namespace std;

int mx=0,mi=2e9,n,q,a[m][m],ans[n],tot;

int lowbit(int x)

struct node q[p],b[p];

struct tree

} int sum(int x,int y)

return res;

}} t;

int get(int lx,int ly,int rx,int ry)

void erfen(int l,int r,int l,int r)

for(int i=l; i<=r; i++)

for(int i=l; i,mi=min(mi,x),mx=max(mx,x);

for(int i=1; i<=q; i++)scanf("%d%d%d%d%d",&q[i].lx,&q[i].ly,&q[i].rx,&q[i].ry,&q[i].k),q[i].id=i;

erfen(mi,mx,1,tot);

for(int i=1; i<=q; i++)printf("%d\n",ans[i]);

return 0;

}

BZOJ 2738 矩陣乘法 整體二分

題目大意 給出乙個n n的矩陣,每次詢問乙個子矩形的第k小數。整體二分即在二分答案的同時把詢問分到兩個集合中再分別二分直到每個詢問出解。相當於把多個詢問一起二分 如何判斷乙個數x是不是k小呢 把矩陣中的小於等於x的數設為1,大於x的數設為0,求詢問矩陣中的小於等於x的數有多少個,大於等於k說明x有可...

BZOJ 2738 矩陣乘法 整體二分

給你乙個n n的矩陣,不用算矩陣乘法,但是每次詢問乙個子矩形的第k小數。愚蠢的名字.整體二分,影響因子就是矩陣裡的數 把 le mid 的矩陣元素加到二維樹狀陣列裡然後詢問分成兩組就行了 可以把矩陣元素權值排序後直接二分矩陣元素而不是值 複雜度 o nlog 3n 用排序代替一維樹狀陣列理論上更快,...

bzoj2738 矩陣乘法 整體二分

題意 求出子矩陣 k 小值。果然除了最小割題面給什麼演算法不能用什麼演算法 實際上區間 k 大值離線通解大概就是整體二分吧 二分最大值和最小值,動態維護,如果這個區間有這麼多個小於它的數,就設為 mid 接下來繼續遞迴修改。1 include 2 include 3 include 4 includ...