POJ2155 Matrix(二维线段树)
2016-06-03 10:56
501 查看
题目大意:
有一个n*n的由零组成的矩阵,给定q个操作,C为将x1y1为左下角,x2y2为右下角的矩阵取反值。Q为输出xy的的0,1状态。
思路:二维线段树(树套树)的建造和访问:
有一个n*n的由零组成的矩阵,给定q个操作,C为将x1y1为左下角,x2y2为右下角的矩阵取反值。Q为输出xy的的0,1状态。
思路:二维线段树(树套树)的建造和访问:
# include<stdio.h> # include<stdlib.h> # include<string.h> int a[4010][4010],n,m,ans; char s[1000]; void buildy(int t,int r,int l,int k,int y1,int y2){//第二维建造 if(r==y1 && l==y2){ a[t][k]^=1; return; } if((r+l)/2>=y2) buildy(t,r,(r+l)/2,k*2,y1,y2); else if(y1>(r+l)/2) buildy(t,(r+l)/2+1,l,k*2+1,y1,y2); else { buildy(t,r,(r+l)/2,k*2,y1,(r+l)/2); buildy(t,(r+l)/2+1,l,k*2+1,(r+l)/2+1,y2); } } void buildx(int t,int r,int l,int x1, int y1, int x2, int y2){//建树 if(r==x1 && l==x2){ buildy(t,1,n,1,y1,y2); return; } if((r+l)/2>=x2) buildx(2*t,r,(r+l)/2,x1,y1,x2,y2); else if(x1>(r+l)/2) buildx(2*t+1,(r+l)/2+1,l,x1,y1,x2,y2); else { buildx(2*t,r,(r+l)/2,x1,y1,(r+l)/2,y2); buildx(2*t+1,(r+l)/2+1,l,(l+r)/2+1,y1,x2,y2); } } void findy(int t,int r,int l,int k,int y){//查询二维 ans^=a[t][k]; if(l==r)return; if((r+l)/2>=y){ findy(t,r,(r+l)/2,k*2,y); } else findy(t,(r+l)/2+1,l,k*2+1,y); } void findx(int t,int r,int l,int x,int y){//查询 findy(t,1,n,1,y); if(r==l)return; if((r+l)/2>=x) findx(t*2,r,(r+l)/2,x,y); else findx(t*2+1,(r+l)/2+1,l,x,y); } int main(){ int l,i,t,x1,x2,y1,y2,x,y,c; scanf("%d",&t); for(l=1;l<=t;l++){ memset(a,0,sizeof(a)); scanf("%d%d",&n,&m); for(i=1;i<=m;i++){ scanf("%s",s); if(*s=='C'){ scanf("%d%d%d%d",&x1,&y1,&x2,&y2); buildx(1,1,n,x1,y1,x2,y2); }else{ ans=0; scanf("%d%d",&x,&y); findx(1,1,n,x,y); printf("%d\n",ans);//输出 } } if(l<t)puts(""); } }
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- C#数据结构之顺序表(SeqList)实例详解
- Lua和C语言的交互详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- C语言练习题:自由落体的小球简单实例
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法