主席树板子求助
查看原帖
主席树板子求助
131591
蒟蒻君HJT泽渡透香楼主2021/12/27 16:19
#include <bits/stdc++.h>
using namespace std;
int R,C,m,a,b,c,d,e;
int v[201][201];
int val,rooted[500001];
struct node{
	int l,r,ls,rs,cnt,sum;
};
node tree[11*500000+1001];
int tot=0;
void work1(){
	int dp[201][201][1001][2];
	for(int i=1;i<=R;i++)for(int j=1;j<=C;j++) scanf("%d",&v[i][j]);
	for(int i=1;i<=1000;i++)for(int j=1;j<=R;j++)for(int k=1;k<=C;k++)
		dp[j][k][i][0]=dp[j-1][k][i][0]+dp[j][k-1][i][0]
		-dp[j-1][k-1][i][0]+(v[j][k]>=i?v[j][k]:0),
		dp[j][k][i][1]=dp[j-1][k][i][1]+dp[j][k-1][i][1]
		-dp[j-1][k-1][i][1]+(v[j][k]>=i?1:0);
	int ans;int l=1,r=1000,mid;int anss,ansss;
	for(int i=1;i<=m;i++){
		ans=0;
		scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);
		if(dp[c][d][1][0]+dp[a-1][b-1][1][0]
		-dp[a-1][d][1][0]-dp[c][b-1][1][0]<e){
			printf("Poor QLW\n");
			continue;
		}
		l=1,r=1000;
		while(l<r){
			mid=(l+r+1)>>1;
			ans=dp[c][d][mid][0]+dp[a-1][b-1][mid][0]
			-dp[a-1][d][mid][0]-dp[c][b-1][mid][0];
			if(ans>=e) l=mid;
			else r=mid-1;
		}
		anss=dp[c][d][l+1][0]+dp[a-1][b-1][l+1][0]
			-dp[a-1][d][l+1][0]-dp[c][b-1][l+1][0];
		ansss=dp[c][d][l+1][1]+dp[a-1][b-1][l+1][1]
			-dp[a-1][d][l+1][1]-dp[c][b-1][l+1][1];
		printf("%d\n",(e-anss+l-1)/l+ansss);
	}
	return ;
}
int build(int l,int r){
	++tot;int las=tot;
	tree[las].l=l;tree[las].r=r;tree[las].cnt=0;tree[las].sum=0;
	if(l==r) return las;
	int mid=(l+r)>>1;
	tree[las].ls=build(l,mid);tree[las].rs=build(mid+1,r);
	return las;
}
inline int upd(int now,int v){
	++tot;tree[tot]=tree[now];tree[tot].cnt++;tree[tot].sum+=v;
	if(tree[now].l==tree[now].r) return tot;
	int las=tot,mid=(tree[now].l+tree[now].r)>>1;
	if(v<=mid) tree[las].ls=upd(tree[now].ls,v);
	else tree[las].rs=upd(tree[now].rs,v);
	return las;
}
int ask_sum(int now,int l,int r){
	if(tree[now].l==l && tree[now].r==r) return tree[now].sum;
	int mid=(tree[now].l+tree[now].r)>>1;
	if(r<=mid) return ask_sum(tree[now].ls,l,r);
	else if(l>=mid+1) return ask_sum(tree[now].rs,l,r);
	return ask_sum(tree[now].ls,l,mid)+ask_sum(tree[now].rs,mid+1,r);
}
int ask_cnt(int now,int l,int r){
	if(tree[now].l==l && tree[now].r==r) return tree[now].cnt;
	int mid=(tree[now].l+tree[now].r)>>1;
	if(r<=mid) return ask_cnt(tree[now].ls,l,r);
	else if(l>=mid+1) return ask_cnt(tree[now].rs,l,r);
	return ask_cnt(tree[now].ls,l,mid)+ask_cnt(tree[now].rs,mid+1,r);
}
void work2(){
	rooted[0]=build(1,1000);
	for(int i=1;i<=C;i++){
		scanf("%d",&val);
		rooted[i]=upd(rooted[i-1],val);
	}
	int l,r,mid,now;
	for(int i=1;i<=m;i++){
		scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);
		if(ask_sum(rooted[d],1,1000)-ask_sum(rooted[b-1],1,1000)<e){
			printf("Poor QLW\n");
			continue;
		}
		l=1,r=1000;
		while(l<r){
			mid=(l+r+1)>>1;
			now=ask_sum(rooted[d],mid,1000)-ask_sum(rooted[b-1],mid,1000);
			if(now>=e) l=mid;
			else r=mid-1;
		}
		if(l<1000)
		now=ask_sum(rooted[d],l+1,1000)-ask_sum(rooted[b-1],l+1,1000);
		else now=0;
		printf("%d\n",
		ask_cnt(rooted[d],l+1,1000)-ask_cnt(rooted[b-1],l+1,1000)+(e-now+l-1)/l);
	}
	return ;
}
int main(){
	freopen("2.in","r",stdin);
	freopen("21.out","w",stdout);
	scanf("%d%d%d",&R,&C,&m);
	if(R>1) work1();
	else work2();
	return 0;
}
2021/12/27 16:19
加载中...