记录编号 |
361672 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
[国家集训队2012]矩阵乘法 |
最终得分 |
100 |
用户昵称 |
FoolMike |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
15.344 s |
提交时间 |
2017-01-04 20:02:07 |
内存使用 |
20.58 MiB |
显示代码纯文本
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=510,M=6e5+10;
int n,q,a[N][N],ans[M];
struct opt{
int x1,x2,y1,y2,k,id,tp;
}Q[M];
struct bit{
int a[N];
void add(int p,int d){
for (;p<=n;p+=p&-p) a[p]+=d;
}
int sum(int r){
int ans=0;
for (;r;r-=r&-r) ans+=a[r];
return ans;
}
};
struct RMQ{
bit a[N];
void add(int x,int y,int d){
for (;x<=n;x+=x&-x) a[x].add(y,d);
}
int sum(int x,int y){
int ans=0;
for (;x;x-=x&-x) ans+=a[x].sum(y);
return ans;
}
int sum(int x1,int y1,int x2,int y2){
return sum(x2,y2)-sum(x2,y1-1)-sum(x1-1,y2)+sum(x1-1,y1-1);
}
}T;
bool cmp(const opt &x,const opt &y){
return x.tp==y.tp?x.id<y.id:x.tp<y.tp;
}
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[Q[i].id]=l;
return;
}
int mid=(l+r)>>1,nl=0;
for (int i=L;i<=R;i++)
if (!Q[i].id){
if (Q[i].k<=mid){
T.add(Q[i].x1,Q[i].y1,1);
Q[i].tp=0;
++nl;
}
else Q[i].tp=1;
}
else{
int sum=T.sum(Q[i].x1,Q[i].y1,Q[i].x2,Q[i].y2);
if (Q[i].k>sum){
Q[i].k-=sum;
Q[i].tp=1;
}
else Q[i].tp=0,++nl;
}
for (int i=L;i<=R;i++)
if (!Q[i].id&&Q[i].k<=mid)
T.add(Q[i].x1,Q[i].y1,-1);
sort(Q+L,Q+R+1,cmp);
solve(L,L+nl-1,l,mid);
solve(L+nl,R,mid+1,r);
}
int main()
{
freopen("nt2012_mat.in","r",stdin);
freopen("nt2012_mat.out","w",stdout);
scanf("%d%d",&n,&q);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++){
scanf("%d",&a[i][j]);
int pos=(i-1)*n+j;
Q[pos].x1=i;Q[pos].y1=j;Q[pos].k=a[i][j];
}
for (int i=n*n+1;i<=n*n+q;i++){
scanf("%d%d%d%d%d",&Q[i].x1,&Q[i].y1,&Q[i].x2,&Q[i].y2,&Q[i].k);
Q[i].id=i-n*n;
}
solve(1,n*n+q,1,1e9);
for (int i=1;i<=q;i++) printf("%d\n",ans[i]);
return 0;
}