您的位置:首页 > 其它

bzoj千题计划150:bzoj2738: 矩阵乘法

2017-12-19 14:29 429 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=2738

整体二分

二维树状数组累积

#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;

#define N 501
#define M 60001

#define lowbit(x) x&-x

struct Number
{
int x,y,num;
}e[N*N];

struct Query
{
int X1,Y1,X2,Y2;
int k,cur;
int id;
}f[M],tmp1[M],tmp2[M];

int n;

int c

;

int ans[M],have[M];

void read(int &x)
{
x=0; char c=getchar();
while(!isdigit(c))  c=getchar();
while(isdigit(c)) { x=x*10+c-'0'; c=getchar();  }
}

bool cmp(Number p,Number q)
{
return p.num<q.num;
}

void change(int x,int y,int w)
{
for(int i=x;i<=n;i+=lowbit(i))
for(int j=y;j<=n;j+=lowbit(j))
c[i][j]+=w;
}

int query(int x,int y)
{
int sum=0;
for(int i=x;i;i-=lowbit(i))
for(int j=y;j;j-=lowbit(j))
sum+=c[i][j];
return sum;
}

void solve(int head,int tail,int l,int r)
{
if(head>tail) return;
if(l==r)
{
for(int i=head;i<=tail;++i) ans[f[i].id]=e[l].num;
return;
}
int mid=l+r>>1;
for(int i=l;i<=mid;++i) change(e[i].x,e[i].y,1);
for(int i=head;i<=tail;++i)
have[f[i].id]=query(f[i].X2,f[i].Y2)-query(f[i].X1-1,f[i].Y2)-query(f[i].X2,f[i].Y1-1)+query(f[i].X1-1,f[i].Y1-1);
for(int i=l;i<=mid;++i) change(e[i].x,e[i].y,-1);
int ll=0,rr=0;
for(int i=head;i<=tail;++i)
{
if(have[f[i].id]+f[i].cur>=f[i].k) tmp1[++ll]=f[i];
else
{
f[i].cur+=have[f[i].id];
tmp2[++rr]=f[i];
}
}
for(int i=1;i<=ll;++i) f[head+i-1]=tmp1[i];
for(int i=1;i<=rr;++i) f[head+ll+i-1]=tmp2[i];
solve(head,head+ll-1,l,mid);
solve(head+ll,tail,mid+1,r);
}

int main()
{
int q;
read(n); read(q);
int tot=0;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
{
e[++tot].x=i;
e[tot].y=j;
read(e[tot].num);
}
sort(e+1,e+tot+1,cmp);
for(int i=1;i<=q;++i)
{
read(f[i].X1);
read(f[i].Y1);
read(f[i].X2);
read(f[i].Y2);
read(f[i].k);
f[i].id=i;
}
solve(1,q,1,tot);
for(int i=1;i<=q;++i) cout<<ans[i]<<'\n';
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: