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

2022-05-01 20:21:10 字數 1237 閱讀 5679

題目大意:給定乙個$n*n$的矩陣。每次給定乙個矩陣求矩陣$k$小值。

注釋:$1\le n\le 500$,$1\le q\le 6\cdot 10^4$。

想法

新操作整體二分。

整體二分是乙個必須離線的演算法而且所求的答案必須滿足單調性。

所謂單調性就是比如這個題:k越大那麼對應的答案越大。

進而我們將所有操作在權值上整體二分。

每次假設當前權值區間為$[l,r]$。

先用二維樹狀陣列求出每個矩形[l,mid]中的點個數然後暴力轉移即可。

暴力轉移就是看一下$k_i$和個數哪個比較大,考慮把當前操作扔進左區間還是右區間。

code:

#include #include #include #include #define n 510 

#define m 60010

using namespace std;

int tree[n<<1][n<<1],ans[m],n,m;

struct pnt a[n*n]; inline bool cmp(const pnt &a,const pnt &b)

void solve(int x,int y,int l,int r)

int mid=(l+r)>>1;

for(int i=l;i<=mid;i++) update(a[i].x,a[i].y,1);

for(int i=x;i<=y;i++)

for(int i=x;i<=y;i++) q[i]=t[i];

for(int i=l;i<=mid;i++) update(a[i].x,a[i].y,-1);

solve(x,tr,l,mid); solve(tl,y,mid+1,r);

}int main()

sort(a+1,a+n*n+1,cmp);

for(int i=1;i<=m;i++) q[i].x1=rd(),q[i].y1=rd(),q[i].x2=rd(),q[i].y2=rd(),q[i].k=rd(),q[i].id=i;

solve(1,m,1,n*n);

for(int i=1;i<=m;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...