您的位置:首页 > 其它

bzoj 2738 矩阵乘法

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

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,qq;
int map[506][505];
int p[60005];
int ans[60005];
struct node
{
int x1,x2,y1,y2,k;
}op[60005];
struct nd
{
int x,y,w;
friend bool operator < (nd aa,nd bb)
{
return aa.w<bb.w;
}
}la[505*505];int tot;
int c[505][505];
void add(int x,int y,int z)
{
for(int i=x;i<=n;i+=(i&(-i)))
{
for(int j=y;j<=n;j+=(j&(-j)))
{
c[i][j]+=z;
}
}
}
int qur(int x,int y)
{
int ans=0;
for(int i=x;i;i-=(i&(-i)))
{
for(int j=y;j;j-=(j&(-j)))
{
ans+=c[i][j];
}
}
return ans;
}
int tmp[2][60005];
void solve(int L,int R,int l,int r)
{
if(L>R)return ;
if(l==r)
{
for(int i=L;i<=R;i++)ans[p[i]]=la[l].w;
return ;
}
int mid=(l+r)>>1;
for(int i=l;i<=mid;i++)add(la[i].x,la[i].y,1);
int cnt1=0,cnt2=0;
for(int i=L;i<=R;i++)
{
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);
if(y>=op[p[i]].k)tmp[0][++cnt1]=p[i];
else op[p[i]].k-=y,tmp[1][++cnt2]=p[i];
}
for(int i=l;i<=mid;i++)add(la[i].x,la[i].y,-1);
int l1=L+cnt1-1;
for(int i=1;i<=cnt1;i++)p[L+i-1]=tmp[0][i];
for(int i=1;i<=cnt2;i++)p[l1+i]=tmp[1][i];
solve(L,l1,l,mid);solve(l1+1,R,mid+1,r);
}
int main()
{
scanf("%d%d",&n,&qq);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&map[i][j]);
la[++tot].x=i;la[tot].y=j;la[tot].w=map[i][j];
}
}
sort(la+1,la+tot+1);
for(int i=1;i<=qq;i++)
{
scanf("%d%d%d%d%d",&op[i].x1,&op[i].y1,&op[i].x2,&op[i].y2,&op[i].k);
p[i]=i;
}
solve(1,qq,1,n*n);
for(int i=1;i<=qq;i++)
{
printf("%d\n",ans[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: