bzoj2738 矩陣乘法

2021-07-12 04:09:45 字數 1632 閱讀 9251

time limit: 20 sec  

memory limit: 256 mb

submit: 1183  

solved: 504 [

submit][

status][

discuss]

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

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

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

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

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

2 22 13 4

1 2 1 2 1

1 1 2 2 313

矩陣中數字是109以內的非負整數;

20%的資料:n<=100,q<=1000;

40%的資料:n<=300,q<=10000;

60%的資料:n<=400,q<=30000;

100%的資料:n<=500,q<=60000。 二分

+分治+二維樹狀陣列

(方法和題目名字一點關係都沒有)

二分答案mid,然後將所有數值小於等於mid的插入到二維樹狀陣列中。

詢問每個矩形中小於mid的元素個數,如果數量大於等於k則放左邊,否則放右邊。

左邊的二分範圍為[1,mid],右邊的答案範圍為[mid+1,n],繼續向下分治。

#include#include#include#include#include#include#define f(i,j,n) for(int i=j;i<=n;i++)

#define d(i,j,n) for(int i=j;i>=n;i--)

#define ll long long

#define maxn 505

#define maxm 60005

#define inf 1000000000

using namespace std;

int n,m,mx,mn=inf,cnt,t;

int s[maxn][maxn],ans[maxm],id[maxm],tmp[maxm];

struct dataa[maxn*maxn];

struct quesp[maxm];

inline int read()

while (ch>='0'&&ch<='9')

return x*f;

}inline bool cmp(data a,data b)

f(i,l,r) id[i]=tmp[i];

solve(l,l1-1,l,mid);solve(l1,r,mid+1,r);

}int main()

sort(a+1,a+cnt+1,cmp);

f(i,1,m) p[i].x1=read(),p[i].y1=read(),p[i].x2=read(),p[i].y2=read(),p[i].k=read();

f(i,1,m) id[i]=i;

solve(1,m,0,mx+1);

f(i,1,m) printf("%d\n",ans[i]);

return 0;

}

BZOJ 2738 矩陣乘法

卡時卡的我心塞啊 因為插入操作太多而且沒有順序我們需要在sort後的插入操作上滾來滾去 其實並不需要排序opt陣列,而用int下標排序可避免複製的時間過長。include include include include include define maxn 510 using namespace ...

bzoj2738 矩陣乘法

description 給你乙個n n的矩陣,不用算矩陣乘法,但是每次詢問乙個子矩形的第k小數。input 第一行兩個數n,q,表示矩陣大小和詢問組數 接下來n行n列一共n n個數,表示這個矩陣 再接下來q行每行5個數描述乙個詢問 x1,y1,x2,y2,k表示找到以 x1,y1 為左上角 以 x2...

bzoj2738 矩陣乘法

m id,每次把權值小於等於mi d 的數對應位置上 1 可以用二維bit實現 然後掃瞄當前的詢問,對於乙個詢問看它對應的那個子矩形中已經插入了幾個數,如果插入的數的個數比詢問的 k 大,就說明列舉的答案過大,就把當前詢問加入左邊,否則加入右邊。然後分治下去。整體二分 二維bit include i...