bzoj2738: 矩阵乘法
2738: 矩阵乘法
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1396 Solved: 603
[Submit][Status][Discuss]
Description
给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数。
Input
第一行两个数N,Q,表示矩阵大小和询问组数;
接下来N行N列一共N*N个数,表示这个矩阵;
再接下来Q行每行5个数描述一个询问:x1,y1,x2,y2,k表示找到以(x1,y1)为左上角、以(x2,y2)为右下角的子矩形中的第K小数。
接下来N行N列一共N*N个数,表示这个矩阵;
再接下来Q行每行5个数描述一个询问:x1,y1,x2,y2,k表示找到以(x1,y1)为左上角、以(x2,y2)为右下角的子矩形中的第K小数。
Output
对于每组询问输出第K小的数。
Sample Input
2 2
2 1
3 4
1 2 1 2 1
1 1 2 2 3
2 1
3 4
1 2 1 2 1
1 1 2 2 3
Sample Output
1
3
3
HINT
矩阵中数字是109以内的非负整数;
20%的数据:N<=100,Q<=1000;
40%的数据:N<=300,Q<=10000;
60%的数据:N<=400,Q<=30000;
100%的数据:N<=500,Q<=60000。
题解
整体二分,把正常区间k大的做法中的一维树状数组和二维树状数组就行了。
我把数组开大十倍……就不T了……感觉奥妙重重啊
1 program j01; 2 type xx=record x1,y1,x2,y2,k,id:longint; end; 3 yy=record x,y,w:longint; end; 4 var c:array[0..600,0..600]of longint; 5 op,tmp:array[0..600086]of xx; 6 ans:array[0..600086]of longint; 7 a:array[0..3000000]of yy; 8 tt,n,m,i,j:longint; 9 10 procedure qsort(l,r:longint); 11 var i,j,x:longint;y:yy; 12 begin 13 i:=l;j:=r;x:=a[i].w; 14 repeat 15 while a[i].w<x do inc(i); 16 while x<a[j].w do dec(j); 17 if i<=j then 18 begin 19 y:=a[i];a[i]:=a[j];a[j]:=y; 20 inc(i);dec(j); 21 end; 22 until i>j; 23 if i<r then qsort(i,r); 24 if l<j then qsort(l,j); 25 end; 26 27 procedure add(x,y,dd:longint); 28 var i,j:longint; 29 begin 30 i:=x; 31 while i<=n do 32 begin 33 j:=y; 34 while j<=n do 35 begin 36 inc(c[i,j],dd);j:=j+(j and(-j)); 37 end; 38 i:=i+(i and(-i)); 39 end; 40 end; 41 42 function ask(x,y:longint):longint; 43 var i,j:longint; 44 begin 45 ask:=0;i:=x; 46 while i>0 do 47 begin 48 j:=y; 49 while j>0 do 50 begin 51 inc(ask,c[i,j]);j:=j-(j and(-j)); 52 end; 53 i:=i-(i and(-i)); 54 end; 55 end; 56 57 procedure solve(ql,qr,l,r:longint); 58 var i,tmpp,lt,rt,mid:longint; 59 begin 60 if ql>qr then exit; 61 if l=r then 62 begin 63 for i:=ql to qr do ans[op[i].id]:=a[l].w; 64 exit; 65 end; 66 lt:=ql-1;rt:=qr+1;mid:=(l+r)div 2; 67 for i:=l to mid do 68 add(a[i].x,a[i].y,1); 69 for i:=ql to qr do 70 begin 71 tmpp:=ask(op[i].x2,op[i].y2)-ask(op[i].x2,op[i].y1-1)-ask(op[i].x1-1,op[i].y2)+ask(op[i].x1-1,op[i].y1-1); 72 if tmpp>=op[i].k then 73 begin 74 inc(lt);tmp[lt]:=op[i]; 75 end else 76 begin 77 op[i].k:=op[i].k-tmpp; 78 dec(rt);tmp[rt]:=op[i]; 79 end; 80 end; 81 for i:=l to mid do 82 add(a[i].x,a[i].y,-1); 83 for i:=ql to qr do op[i]:=tmp[i]; 84 solve(ql,lt,l,mid); 85 solve(rt,qr,mid+1,r); 86 end; 87 88 begin 89 readln(n,m); 90 tt:=0; 91 for i:=1 to n do 92 for j:=1 to n do 93 begin 94 inc(tt);a[tt].x:=i;a[tt].y:=j; 95 read(a[tt].w); 96 end; 97 qsort(1,tt); 98 for i:=1 to m do 99 begin 100 read(op[i].x1,op[i].y1,op[i].x2,op[i].y2,op[i].k); 101 op[i].id:=i; 102 end; 103 solve(1,m,1,tt); 104 for i:=1 to m do writeln(ans[i]); 105 end.