bzoj 2738 矩阵乘法

       其实这题跟矩阵乘法没有任何卵关系,直接整体二分,用二维树状数组维护(刚刚学会>_<),复杂度好像有点爆炸(好像有十几亿不知道是不是算错了),但我们不能怂啊23333。

       

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int n,qq;
 7 int map[506][505];
 8 int p[60005];
 9 int ans[60005];
10 struct node
11 {
12     int x1,x2,y1,y2,k;
13 }op[60005];
14 struct nd
15 {
16     int x,y,w;
17     friend bool operator < (nd aa,nd bb)
18     {
19         return aa.w<bb.w;
20     }
21 }la[505*505];int tot;
22 int c[505][505];
23 void add(int x,int y,int z)
24 {
25     for(int i=x;i<=n;i+=(i&(-i)))
26     {
27         for(int j=y;j<=n;j+=(j&(-j)))
28         {
29             c[i][j]+=z;
30         }
31     }
32 }
33 int qur(int x,int y)
34 {
35     int ans=0;
36     for(int i=x;i;i-=(i&(-i)))
37     {
38         for(int j=y;j;j-=(j&(-j)))
39         {
40             ans+=c[i][j];
41         }
42     }
43     return ans;
44 } 
45 int tmp[2][60005];
46 void solve(int L,int R,int l,int r)
47 {
48     if(L>R)return ;
49     if(l==r)
50     {
51         for(int i=L;i<=R;i++)ans[p[i]]=la[l].w;
52         return ;
53     }
54     int mid=(l+r)>>1;
55     for(int i=l;i<=mid;i++)add(la[i].x,la[i].y,1);
56     int cnt1=0,cnt2=0;
57     for(int i=L;i<=R;i++)
58     {
59         int y=qur(op[p[i]].x2,op[p[i]].y2)-qur(op[p[i]].x1-1,op[p[i]].y2)-qur(op[p[i]].x2,op[p[i]].y1-1)+qur(op[p[i]].x1-1,op[p[i]].y1-1);
60         if(y>=op[p[i]].k)tmp[0][++cnt1]=p[i];
61         else op[p[i]].k-=y,tmp[1][++cnt2]=p[i];
62     }
63     for(int i=l;i<=mid;i++)add(la[i].x,la[i].y,-1);
64     int l1=L+cnt1-1;
65     for(int i=1;i<=cnt1;i++)p[L+i-1]=tmp[0][i];
66     for(int i=1;i<=cnt2;i++)p[l1+i]=tmp[1][i];
67     solve(L,l1,l,mid);solve(l1+1,R,mid+1,r);
68 }
69 int main()
70 {
71     scanf("%d%d",&n,&qq);
72     for(int i=1;i<=n;i++)
73     {
74         for(int j=1;j<=n;j++)
75         {
76             scanf("%d",&map[i][j]);
77             la[++tot].x=i;la[tot].y=j;la[tot].w=map[i][j];
78         }
79     }
80     sort(la+1,la+tot+1);
81     for(int i=1;i<=qq;i++)
82     {
83         scanf("%d%d%d%d%d",&op[i].x1,&op[i].y1,&op[i].x2,&op[i].y2,&op[i].k);
84         p[i]=i;
85     }
86     solve(1,qq,1,n*n);
87     for(int i=1;i<=qq;i++)
88     {
89         printf("%d\n",ans[i]);
90     }
91     return 0;
92 }

 

posted @ 2016-12-10 17:32  SD_le  阅读(216)  评论(0编辑  收藏  举报
重置按钮