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

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[N][N]; int ans[M],have[M]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; 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=;
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>>;
for(int i=l;i<=mid;++i) change(e[i].x,e[i].y,);
for(int i=head;i<=tail;++i)
have[f[i].id]=query(f[i].X2,f[i].Y2)-query(f[i].X1-,f[i].Y2)-query(f[i].X2,f[i].Y1-)+query(f[i].X1-,f[i].Y1-);
for(int i=l;i<=mid;++i) change(e[i].x,e[i].y,-);
int ll=,rr=;
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=;i<=ll;++i) f[head+i-]=tmp1[i];
for(int i=;i<=rr;++i) f[head+ll+i-]=tmp2[i];
solve(head,head+ll-,l,mid);
solve(head+ll,tail,mid+,r);
} int main()
{
int q;
read(n); read(q);
int tot=;
for(int i=;i<=n;++i)
for(int j=;j<=n;++j)
{
e[++tot].x=i;
e[tot].y=j;
read(e[tot].num);
}
sort(e+,e+tot+,cmp);
for(int i=;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(,q,,tot);
for(int i=;i<=q;++i) cout<<ans[i]<<'\n';
}
上一篇:大数据系列修炼-Scala课程01


下一篇:Android 高级UI设计笔记20:RecyclerView 的详解之RecyclerView添加Item点击事件