BZOJ2738: 矩阵乘法
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2738
题解:《题目名称与题目解法完全不符系列》
尼玛看了一句题解就知道怎么做了:把数从小到大一个一个加入到网格中!
卧槽我怎么还是没有吸取教训!@随机数生成器
给定矩形区域内的第k大,包括最小值,最大值,只要按顺序从小到大填入,当填入数达到k的时候就是第k大。
然后这题就和那题一样了 @POI2011meteors
代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define inf 1000000000 13 #define maxn 505 14 #define maxm 500000+5 15 #define eps 1e-10 16 #define ll long long 17 #define pa pair<int,int> 18 #define for0(i,n) for(int i=0;i<=(n);i++) 19 #define for1(i,n) for(int i=1;i<=(n);i++) 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 22 #define for4(i,x) for(int i=head[x],z=e[i].go;i;i=e[i].next,z=e[i].go) 23 #define mod 1000000007 24 #define num(x,y) ((x-1)*n+y) 25 using namespace std; 26 inline int read() 27 { 28 int x=0,f=1;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 30 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 31 return x*f; 32 } 33 int n,m,tot,head[maxm],ans[maxm],id[maxm],a[maxm],b[maxm],s[maxn][maxn]; 34 struct rec{int x1,y1,x2,y2,k,id;}q[maxm],p[maxm]; 35 struct edge{int go,next;}e[maxm]; 36 inline void add(int x,int y) 37 { 38 e[++tot]=(edge){y,head[x]};head[x]=tot; 39 } 40 inline void add(int x,int y,int z) 41 { 42 for(;x<=n;x+=x&(-x)) 43 for(int i=y;i<=n;i+=i&(-i)) 44 s[x][i]+=z; 45 } 46 inline int sum(int x,int y) 47 { 48 int t=0; 49 for(;x;x-=x&(-x)) 50 for(int i=y;i;i-=i&(-i)) 51 t+=s[x][i]; 52 return t; 53 } 54 inline bool cmp(int x,int y){return a[x]<a[y];} 55 inline void solve(int l,int r,int x,int y) 56 { 57 if(x>y)return; 58 if(l==r) 59 { 60 for2(i,x,y)ans[q[i].id]=id[l]; 61 return; 62 } 63 int mid=(l+r)>>1,h=x-1,t=y+1; 64 for2(i,l,mid)for4(j,i)add((z-1)/n+1,(z-1)%n+1,1); 65 for2(i,x,y) 66 { 67 int tmp=sum(q[i].x1-1,q[i].y1-1)+sum(q[i].x2,q[i].y2) 68 -sum(q[i].x1-1,q[i].y2)-sum(q[i].x2,q[i].y1-1); 69 if(tmp>=q[i].k)p[++h]=q[i];else p[--t]=q[i],p[t].k-=tmp; 70 } 71 for2(i,l,mid)for4(j,i)add((z-1)/n+1,(z-1)%n+1,-1); 72 for2(i,x,y)q[i]=p[i]; 73 solve(l,mid,x,h);solve(mid+1,r,t,y); 74 } 75 int main() 76 { 77 freopen("input.txt","r",stdin); 78 freopen("output.txt","w",stdout); 79 n=read();m=read(); 80 for1(i,n)for1(j,n)a[num(i,j)]=read(),b[num(i,j)]=num(i,j); 81 sort(b+1,b+n*n+1,cmp); 82 int cnt=0; 83 for1(i,n*n) 84 { 85 if(i==1||a[b[i]]!=a[b[i-1]])cnt++; 86 id[cnt]=a[b[i]]; 87 add(cnt,b[i]); 88 } 89 for1(i,m)q[i].x1=read(),q[i].y1=read(),q[i].x2=read(),q[i].y2=read(),q[i].k=read(),q[i].id=i; 90 solve(1,cnt,1,m); 91 for1(i,m)printf("%d\n",ans[i]); 92 return 0; 93 }