这是什么神奇操作,二分区间初始l 设为0就能100分,设为1,就只有80分,
查看原帖
这是什么神奇操作,二分区间初始l 设为0就能100分,设为1,就只有80分,
368760
chenkejin楼主2021/7/12 20:48

由于数据每一个数都是大于等于1的

那么在统计总和和总个数的时候 大于等于1的查询 和大于等于0的查询答案应该是一样的啊

可就是出现的题目的那种情况

#include<bits/stdc++.h>
using namespace std;
const int N=210,M=1010;
int num[N][N][M];
int val[N][N][M];
int g[N][N];
int n,m,T;
int get_val(int a1,int b1,int a2,int b2,int k){
	return val[a2][b2][k]-val[a2][b1-1][k]-val[a1-1][b2][k]+val[a1-1][b1-1][k];
}
int get_num(int a1,int b1,int a2,int b2,int k){
	return num[a2][b2][k]-num[a2][b1-1][k]-num[a1-1][b2][k]+num[a1-1][b1-1][k];
}
int solve1(){
	int maxv=-1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			scanf("%d",&g[i][j]);
			if(g[i][j]==0)cout<<endl;
			maxv=max(maxv,g[i][j]);
		}
	}
	for(int k=0;k<=maxv;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				num[i][j][k]=num[i][j-1][k]+num[i-1][j][k]-num[i-1][j-1][k]+(g[i][j]>=k?1:0);
				val[i][j][k]=val[i][j-1][k]+val[i-1][j][k]-val[i-1][j-1][k]+(g[i][j]>=k?g[i][j]:0);
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(num[i][j][0]!=num[i][j][1])cout<<1<<endl;
			if(val[i][j][0]!=val[i][j][1])cout<<2<<endl;
		}
	}
	while(T--){
		int x1,y1,x2,y2,h;
		scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&h);
		if(get_val(x1,y1,x2,y2,1)<h){
			cout<<"Poor QLW"<<endl;
			continue;
		}
		int l=0; int r=maxv; int ans=-2;
		while(l<r){
			int mid=l+r+1>>1;
			if(get_val(x1,y1,x2,y2,mid)>=h)l=mid,ans=max(ans,mid);
			else r=mid-1;
		}
		if(ans==-2)cout<<"Poor QLW"<<endl;
		else {
			int res=get_num(x1,y1,x2,y2,ans)-(get_val(x1,y1,x2,y2,ans)-h)/ans;
			cout<<res<<endl;
		}
	}
}
const int NN=5e5+10;
struct node{
	int l,r;
	int cnt,sum;
}tr[NN*4+NN*20];
int root[NN],idx;
int w[NN];
int build(int l,int r){
	int u=++idx;
	if(l==r)return u;
	int mid=l+r>>1;
	tr[u].l=build(l,mid);
	tr[u].r=build(mid+1,r);
	return u;
}
int insert(int p,int l,int r,int k){
	int q=++idx;
	tr[q]=tr[p];
	if(l==r){
		tr[q].cnt=tr[p].cnt+1;
		tr[q].sum+=k;
		return q;
	}
	int mid=l+r>>1;
	if(k<=mid)tr[q].l=insert(tr[p].l,l,mid,k);
	else tr[q].r=insert(tr[p].r,mid+1,r,k);
	int L=tr[q].l; int R=tr[q].r;
	tr[q].cnt=tr[L].cnt+tr[R].cnt;
	tr[q].sum=tr[L].sum+tr[R].sum;
	return q;
}
int query_val(int p,int q,int l,int r,int k){
	if(l>=k){
		return tr[q].sum-tr[p].sum;
	}
	int mid=l+r>>1; int res=0;
	if(k<=mid)res+=tr[tr[q].r].sum-tr[tr[p].r].sum,res+=query_val(tr[p].l,tr[q].l,l,mid,k);
	else res+=query_val(tr[p].r,tr[q].r,mid+1,r,k);
	return res;
}
int query_num(int p,int q,int l,int r,int k){
	if(l>=k){
		return tr[q].cnt-tr[p].cnt;
	}
	int mid=l+r>>1; int res=0;
	if(k<=mid)res+=tr[tr[q].r].cnt-tr[tr[p].r].cnt,res+=query_num(tr[p].l,tr[q].l,l,mid,k);
	else res+=query_num(tr[p].r,tr[q].r,mid+1,r,k);
	return res;
}
int solve2(){
	int maxv=-1;
	for(int i=1;i<=m;i++){
		scanf("%d",&w[i]);
		maxv=max(maxv,w[i]);
	}
	root[0]=build(1,1000);
	for(int i=1;i<=m;i++){
		root[i]=insert(root[i-1],1,1000,w[i]);
	}
	while(T--){
		int x1,y1,x2,y2,h;
		scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&h);
		int temp=query_val(root[y1-1],root[y2],1,1000,1);
		if(temp<h){
			cout<<"Poor QLW"<<endl;
			continue;
		}
		int l=0; int r=maxv;  int ans=-1;
		while(l<r){
			int mid=l+r+1>>1;
			if(query_val(root[y1-1],root[y2],1,1000,mid)>=h)l=mid,ans=mid;
			else r=mid-1;
		}
		int res=query_num(root[y1-1],root[y2],1,1000,ans)-( (query_val(root[y1-1],root[y2],1,1000,ans)-h)/ans );
		cout<<res<<endl;
	}
}
int main(){
	scanf("%d%d%d",&n,&m,&T);
	if(n==1)solve2();
	else solve1();
}
2021/7/12 20:48
加载中...