poj之旅——2155

//仍然没看懂3109,欸。。

题目描述:给出T组数据,每组数据包括n(一个n*n的初始值为0的矩形)与Questions(表示问题的数目),

每个问题可以有两个操作:

C x1,y1,x2,y2:将[x1,y1]到[x2,y2]的子矩阵中的元素进行not操作。

Q x,y:输出[x,y]的值。


题解:

题目要求二维——poj真难为人,一维还没弄清楚,就直接上二维。。而且在这个问题上《挑战程序设计竞赛》一书就做的不够好,在一维中用了两个辅助树状数组,码农场的hankcs则套用模板,显然不够好。

我们先简化问题:

假设有一个序列,n个数。操作相同,只是变成一维的而已。

我们可以维护一个树状数组sum=a[1]+a[2]....+a[i](a表示当前数据not的次数),

对于修改区间[l,r),则可以很巧妙的add(l,x),add(r,-x),一加一减,r以后的则消去了。

//如果读者对此有所疑惑,可见详解

这样就可以很简洁的扩展到二维了,此问题也就巧妙的解决了。


参考程序:

#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 1100
using namespace std;
struct Bit{
	int a[maxn][maxn];
	int n;
	void init(int n){
		this->n=n;
		memset(a,0,sizeof(a));
	}
	int bit(int x){
		return x & (-x);
	}
	void add(int x,int y,int data){
		while (x<=n){
			int ty=y;
			while (ty<=n){
				a[x][ty]+=data;
				ty+=bit(ty);
			}
			x+=bit(x);
		}
	}
	int query(int x,int y){
		int sum=0;
		while (x){
			int ty=y;
			while (ty){
				sum+=a[x][ty];
				ty-=bit(ty);
			}
			x-=bit(x);
		}
		return sum;
	}
}map;
int main(){
	int T;
	scanf("%d",&T);
	while (T--){
		int n,m;
		scanf("%d%d",&n,&m);
		map.init(n);
		for (int sth=0;sth<m;sth++){
			char cmd;
			scanf("\n%c",&cmd);
			if (cmd=='C'){
				int x1,y1,x2,y2;
				scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
				map.add(x1,y1,1);
				map.add(x1,y2+1,1);
				map.add(x2+1,y1,1);
				map.add(x2+1,y2+1,1);
			}else{
				int x,y;
				scanf("%d%d",&x,&y);
				printf("%d\n",map.query(x,y)&1);
			}
		}
		puts("");
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值