记录编号 361672 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2012]矩阵乘法 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 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;
}