牛客寒假6 补题

E-前缀和
链接:https://ac.nowcoder.com/acm/contest/332/E
来源:牛客网
题目描述
有一个沿海地区,可以看作有n行m列的城市,第i行第j列的城市海拔为h[i][j]。
由于沿海,所以这个地区经常会发生海啸。
海啸发生时,部分城市会被淹没,具体来说,海水高度会达到d,因此海拔低于d的城市都会被淹没。
现在有q次询问,每次问你一个矩形区域中,有多少城市不会被淹没。
输入描述:
第一行三个整数n,m,d,具体含义见题目描述。
接下来n行,每行m个整数,其中第i行第j列的整数为h[i][j],具体含义见题目描述。
第n+2行一个整数q,表示询问数。
接下来q行,每行四个整数a,b,x,y,
表示询问从第a行第b列到第x行第y列的矩形地区中,有多少地区不会被淹没。
即有多少个i,j,满足 a≤i≤x,b≤j≤y ,且 h[i][j]≥d 。
输出描述:
共q行,第i行一个整数,表示第i个询问的答案。
示例1
输入
3 3 3
1 2 3
2 1 5
4 3 2
2
1 2 2 3
2 1 3 3
输出
2
3
备注:
1≤n×m≤10^6
1≤q≤10^5
0≤d,h[i][j]≤10^9
1≤a≤x≤n,1≤b≤y≤m
解题思路:
前缀和
代码:

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    	int x=0,f=0;char ch=getchar();
    	while(ch>'9'||ch<'0')f|=ch=='-',ch=getchar();
    	while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    	return f?-x:x;
}
const int maxn=1e6+3;
int mp[maxn],bit[maxn],n,m,d;
int lowbit(int x){return x&-x;}
inline void add(int x,int y,int num){
	for(int i=x;i<=n;i+=lowbit(i))for(int j=y;j<=m;j+=lowbit(j))bit[i*m-m+j]+=num;
}
inline int sum(int a,int b){
	int ans=0;
	for(int i=a;i;i-=lowbit(i))for(int j=b;j;j-=lowbit(j))ans+=bit[i*m-m+j];
	return ans;
}
int main(){
	n=read(),m=read(),d=read();
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
			if(read()>=d)add(i,j,1);
	int q=read();
	while(q--){
		int lu=read(),ru=read(),ld=read(),rd=read();
		printf("%d\n",sum(ld,rd)-sum(lu-1,rd)-sum(ld,ru-1)+sum(lu-1,ru-1));
	}
	return 0;
}

G-找规律
链接:https://ac.nowcoder.com/acm/contest/332/G
来源:牛客网

题目描述
求a|(a+1)|(a+2)|…|(b-1)|b。
其中|表示按位或
输入描述:
多组输入,每行两个数表示a和b
输出描述:
对于每组输入,输出一个数a|(a+1)|(a+2)|…|(b-1)|b。
示例1
输入
99 109
68 77
55 66
34 43
1111234 1114321
输出
111
79
127
47
1179647
备注:
输入不超过10000行,
0≤a,b≤10^18,a≤b
解题思路:
二进制下,比较l,r两数第一个不同的位置,后面都变成1
代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
	ll l,r;
	while(~scanf("%lld%lld",&l,&r)){
		if(l==r-1){
			printf("%lld\n",l|r);
			continue;
		}
		int p=log2(r);
		for(int i=p;i>=0;--i){
			if(((l>>i)&1)==((r>>i)&1))continue;
			r|=((1ll<<i)-1);
			break;
		}
		printf("%lld\n",r);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值