jzoj2908,P1527-[集训队互测 2012]矩阵乘法【整体二分,二维树状数组】
生活随笔
收集整理的這篇文章主要介紹了
jzoj2908,P1527-[集训队互测 2012]矩阵乘法【整体二分,二维树状数组】
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
正題
題目鏈接:https://www.luogu.org/problem/P1527
題目大意
給出一個(gè)矩陣,每個(gè)詢問(wèn)求子矩陣中的第kkk小數(shù)。
解題思路
我們發(fā)現(xiàn)我們對(duì)于每個(gè)詢問(wèn)我們可以二分答案,然后查找該子矩陣中有多少個(gè)數(shù)≤mid\leq mid≤mid來(lái)判斷。
但是這樣時(shí)間復(fù)雜度和空間復(fù)雜度顯然無(wú)法接受。
所以我們考慮整體二分,我們將所有的詢問(wèn)放在一起二分,然后單獨(dú)處理左邊的,再處理右邊的。其中我們可以用二維樹(shù)狀數(shù)組可以在O(mid+qlog?2n)O(mid+q\log^2 n)O(mid+qlog2n)的時(shí)間內(nèi)處理子矩陣中有多少個(gè)數(shù)≤mid\leq mid≤mid
codecodecode
// luogu-judger-enable-o2 #include<cstdio> #include<cstring> #include<algorithm> #define lowbit(x) (x&-x) using namespace std; const int N=510,M=61000; int n,m,t[N][N],cnt,ans[M],last; struct node{int x,y,w; }a[N*N]; struct Que_node{int x1,y1,x2,y2,k,pos; }q[M],q1[M],q2[M]; void change(int x,int y,int val) {for(int i=x;i<=n;i+=lowbit(i))for(int j=y;j<=n;j+=lowbit(j))t[i][j]+=val;return; } int ask(int x,int y) {int ans=0;for(int i=x;i;i-=lowbit(i))for(int j=y;j;j-=lowbit(j))ans+=t[i][j];return ans; } int query(int x1,int y1,int x2,int y2) {return ask(x2,y2)+ask(x1-1,y1-1)-ask(x1-1,y2)-ask(x2,y1-1);} void get_ans(int l,int r,int L,int R) {int mid=(l+r)>>1;if(L>R) return;if(l==r){for(int i=L;i<=R;i++)ans[q[i].pos]=a[l].w;return;}for(int i=l;i<=mid;i++)change(a[i].x,a[i].y,1);int cnt1=0,cnt2=0;for(int i=L;i<=R;i++){int x=query(q[i].x1,q[i].y1,q[i].x2,q[i].y2);if(x>=q[i].k) q1[++cnt1]=q[i];else q[i].k-=x,q2[++cnt2]=q[i];}for(int i=l;i<=mid;i++)change(a[i].x,a[i].y,-1);int z=L-1;for(int i=1;i<=cnt1;i++)q[++z]=q1[i];for(int i=1;i<=cnt2;i++)q[++z]=q2[i];get_ans(l,mid,L,L+cnt1-1);get_ans(mid+1,r,L+cnt1,R);return; } bool cMp(node x,node y) {return x.w<y.w;} int main() {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){int x;scanf("%d",&x);a[++cnt]=(node){i,j,x};}sort(a+1,a+1+cnt,cMp);for(int i=1;i<=m;i++)scanf("%d%d%d%d%d",&q[i].x1,&q[i].y1,&q[i].x2,&q[i].y2,&q[i].k),q[i].pos=i;get_ans(1,cnt,1,m);for(int i=1;i<=m;i++)printf("%d\n",ans[i]); } /* 3 3 2 0 6 3 4 0 8 9 5 1 2 2 3 1 1 1 3 3 7 */總結(jié)
以上是生活随笔為你收集整理的jzoj2908,P1527-[集训队互测 2012]矩阵乘法【整体二分,二维树状数组】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Org-mode, 用文本文件管理日常十
- 下一篇: jzoj3410-[GDOI2014模拟