bzoj2738 矩阵乘法 整体二分

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2738

题意:求出子矩阵$K$小值。

果然除了最小割题面给什么算法不能用什么算法

这个玩意……实际上并没有强制在线的要求……退一步讲这个时空要求也不太适合主席树……然而……$wcx$神犇正面硬上……结果在$MLE$和$RE$间抓狂了一下午……

实际上区间$K$大值离线通解大概就是整体二分吧……二分最大值和最小值,动态维护,如果这个区间有这么多个小于它的数,就设为$mid$,接下来继续递归修改。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn=505,maxq=60005;
 7 int C[maxn][maxn],n,q,cnt;
 8 int lowbit(int x)
 9 {
10     return x&(-x);
11 }
12 int Query(int x,int y)
13 {
14     int res=0;
15     for(;x;x-=lowbit(x))
16         for(int j=y;j;j-=lowbit(j))res+=C[x][j];
17     return res;
18 }
19 void Modify(int x,int y,int val)
20 {
21     for(;x<=n;x+=lowbit(x))
22         for(int j=y;j<=n;j+=lowbit(j))C[x][j]+=val;
23 }
24 struct point
25 {
26     int x,y,val;
27     bool operator <(const point &b)const
28     {
29         return val<b.val;
30     }
31 }P[maxn*maxn];
32 struct ques
33 {
34     int x1,y1,x2,y2,k;
35 }Q[maxq];
36 int id[maxq],tmp[maxq],ans[maxq],T;
37 bool vis[maxq];
38 int query(int x)
39 {
40     int x1=Q[x].x1,x2=Q[x].x2,y1=Q[x].y1,y2=Q[x].y2;
41     return Query(x2,y2)-Query(x1-1,y2)-Query(x2,y1-1)+Query(x1-1,y1-1);
42 }
43 void Solve(int l,int r,int L,int R)
44 {
45     if(l>r)return;if(L==R)return;
46     int mid=(L+R)>>1;
47     while(P[T+1].val<=mid&&T<cnt)Modify(P[T+1].x,P[T+1].y,1),T++;
48     while(P[T].val>mid)Modify(P[T].x,P[T].y,-1),T--;
49     int num=0;
50     for(int i=l;i<=r;i++)
51     {
52         if(query(id[i])>=Q[id[i]].k)vis[i]=1,ans[id[i]]=mid,num++;
53         else vis[i]=0;
54     }
55     int l1=l,l2=l+num;
56     for(int i=l;i<=r;i++)
57         if(vis[i])tmp[l1++]=id[i];else tmp[l2++]=id[i];
58     for(int i=l;i<=r;i++)id[i]=tmp[i];
59     Solve(l,l1-1,L,mid);Solve(l1,l2-1,mid+1,R);
60 }
61 int haha()
62 {
63     scanf("%d%d",&n,&q);int maxx=0;
64     for(int i=1;i<=n;i++)
65         for(int j=1;j<=n;j++)
66         {
67             P[++cnt].x=i,P[cnt].y=j;
68             scanf("%d",&P[cnt].val);maxx=max(P[cnt].val,maxx);
69         }
70     sort(P+1,P+cnt+1);
71     for(int i=1;i<=q;i++)scanf("%d%d%d%d%d",&Q[i].x1,&Q[i].y1,&Q[i].x2,&Q[i].y2,&Q[i].k);
72     for(int i=1;i<=q;i++)id[i]=i;
73     Solve(1,q,0,maxx+1);
74     for(int i=1;i<=q;i++)printf("%d\n",ans[i]);
75 }
76 int sb=haha();
77 int main(){;}
bzoj2738

 

posted @ 2017-10-03 11:09  ccc000111  阅读(169)  评论(0编辑  收藏  举报