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 }
View Code

 

posted @ 2015-02-01 16:45  ZYF-ZYF  Views(357)  Comments(0Edit  收藏  举报