hdu5465
2015-11-05 20:43
197 查看
这道题明显是博弈+二维线段树,但是不知道怎么写出了时间排名倒几的程序。
已ac的代码:
参考链接:
http://blog.csdn.net/dingding_tao/article/details/48596601
看别人的题解使用二维树状数组做的,于是就又写了一遍,结果发现我理解的二维数组只不过是很多一维数组的集合罢了
,将近超时。
将近超时的ac的代码:
真正的二维数组,果然速度快好多。
ac的代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 510
int bit
;
int cnum
;
int n,m;
int lowbit(int x){
return ((~x)+1)&x;
}
int query(int x,int y){
int ans=0;
for(int i=x;i;i=i-lowbit(i)){
for(int j=y;j;j=j-lowbit(j)){
ans^=bit[i][j];
}
}
return ans;
}
void change(int x,int y,int changeto){
for(int i=x;i<=n;i=i+lowbit(i)){
for(int j=y;j<=m;j=j+lowbit(j)){
bit[i][j]^=changeto;
}
}
return;
}
int main(){
int t;
int q;
int op;
int x1,y1,x2,y2;
int ans;
int changeto;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m,&q);
memset(bit,0,sizeof(bit));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&cnum[i][j]);
change(i,j,cnum[i][j]);
}
}
for(int i=0;i<q;i++){
scanf("%d",&op);
if(op==1){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
ans=query(x2,y2)^query(x1-1,y2)^query(x2,y1-1)^query(x1-1,y1-1);
if(ans==0){
printf("No\n");
}
else{
printf("Yes\n");
}
}
else{
scanf("%d%d%d",&x1,&y1,&changeto);
change(x1,y1,changeto^cnum[x1][y1]);
cnum[x1][y1]=changeto;
}
}
}
return 0;
}
已ac的代码:
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define N 510 #pragma comment(linker, "/STACK:1024000000,1024000000") int ornum[N*N*10]; int allx1,ally1,allx2,ally2; int changeto; int cnum ; void create(int root,int x1,int y1,int x2,int y2){ if(x1==x2&&y1==y2){ ornum[root]=cnum[x1][y1]; //printf("%d %d %d %d %d\n",x1,y1,x2,y2,ornum[root]); } else{ int xmiddle=(x1+x2)>>1; int ymiddle=(y1+y2)>>1; create((root<<2)+1,x1,y1,xmiddle,ymiddle); if(y1!=y2){ create((root<<2)+2,x1,ymiddle+1,xmiddle,y2); } else{ ornum[(root<<2)+2]=0; } if(x1!=x2){ create((root<<2)+3,xmiddle+1,y1,x2,ymiddle); } else{ ornum[(root<<2)+3]=0; } if(x1!=x2&&y1!=y2){ create((root<<2)+4,xmiddle+1,ymiddle+1,x2,y2); } else{ ornum[(root<<2)+4]=0; } ornum[root]=ornum[(root<<2)+1]^ornum[(root<<2)+2]^ornum[(root<<2)+3]^ornum[(root<<2)+4];//ornum[(root<<2)+2]写成了ornum[(root)<<2+2],于是就一直有问题 } return; } int query(int root,int x1,int y1,int x2,int y2){ if(allx1<=x1&&allx2>=x2&&ally1<=y1&&ally2>=y2){//把x,y和allx,ally之间的关系想反了,所以这里写反了,大于等于和小于等于左右两边写反了。 return ornum[root]; } else{ int xmiddle=(x1+x2)>>1; int ymiddle=(y1+y2)>>1; int ans=0; if(allx1<=xmiddle){ if(ally1<=ymiddle){ ans^=query((root<<2)+1,x1,y1,xmiddle,ymiddle); } if(ally2>ymiddle&&y1!=y2){ ans^=query((root<<2)+2,x1,ymiddle+1,xmiddle,y2);//这里写成了xmiddle+1,y1,所以一直栈溢出? } } if(allx2>xmiddle&&x1!=x2){ if(ally1<=ymiddle){ ans^=query((root<<2)+3,xmiddle+1,y1,x2,ymiddle); } if(ally2>ymiddle&&y1!=y2){ ans^=query((root<<2)+4,xmiddle+1,ymiddle+1,x2,y2); } } return ans; } } void change(int root,int x1,int y1,int x2,int y2){ if(x1==x2&&y1==y2){ ornum[root]=changeto; } else{ int xmiddle=(x1+x2)>>1; int ymiddle=(y1+y2)>>1; if(allx1<=xmiddle&&ally1<=ymiddle){ change((root<<2)+1,x1,y1,xmiddle,ymiddle); } else if(allx1<=xmiddle&&ally1>ymiddle){ change((root<<2)+2,x1,ymiddle+1,xmiddle,y2); } else if(allx1>xmiddle&&ally1<=ymiddle){ change((root<<2)+3,xmiddle+1,y1,x2,ymiddle); } else{ change((root<<2)+4,xmiddle+1,ymiddle+1,x2,y2); } ornum[root]=ornum[(root<<2)+1]^ornum[(root<<2)+2]^ornum[(root<<2)+3]^ornum[(root<<2)+4]; } return; } int main(){ int t; int n,m,q; int op; //int x1,x2,y1,y2; scanf("%d",&t); while(t--){ scanf("%d%d%d",&n,&m,&q); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&cnum[i][j]);//二维线段树不像一维的,可以在建树是输入,因为二维的如果这样做,会错乱。 } } create(0,1,1,n,m); //printf("wo shi da hao ren"); for(int i=0;i<q;i++){ scanf("%d",&op); if(op==1){ scanf("%d%d%d%d",&allx1,&ally1,&allx2,&ally2); //printf("%d %d %d %d\n",allx1,ally1,allx2,ally2); /*printf("Yes\n");*/ //printf("%d %d\n",query(0,1,1,n,m),ornum[0]); if(query(0,1,1,n,m)==0){//猜测:query使得栈溢出 printf("No\n"); } else{ printf("Yes\n"); } } else{ scanf("%d%d%d",&allx1,&ally1,&changeto); change(0,1,1,n,m); } } } return 0; }
参考链接:
http://blog.csdn.net/dingding_tao/article/details/48596601
看别人的题解使用二维树状数组做的,于是就又写了一遍,结果发现我理解的二维数组只不过是很多一维数组的集合罢了
,将近超时。
将近超时的ac的代码:
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define N 510 int bit ; int cnum ; int n,m; int lowbit(int x){ return x&((~x)+1); } void change(int x,int y,int from,int changeto){ while(y<=m){ bit[x][y]^=from; bit[x][y]^=changeto; y=y+lowbit(y); } return; } int query(int x1,int y1,int x2,int y2){ int ans=0; for(int i=x1;i<=x2;i++){ for(int j=y1-1;j>0;j-=lowbit(j)){ ans^=bit[i][j]; } for(int j=y2;j>0;j-=lowbit(j)){ ans^=bit[i][j]; } } return ans; } int main(){ int t; int q; int tempnum; int op; int x1,y1,x2,y2; int ans; int changeto; scanf("%d",&t); while(t--){ scanf("%d%d%d",&n,&m,&q); memset(bit,0,sizeof(bit)); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&tempnum); change(i,j,0,tempnum); cnum[i][j]=tempnum; } } for(int i=0;i<q;i++){ scanf("%d",&op); if(op==1){ scanf("%d%d%d%d",&x1,&y1,&x2,&y2); ans=0; ans=ans^query(x1,y1,x2,y2); if(ans==0){ printf("No\n"); } else{ printf("Yes\n"); } } else{ scanf("%d%d%d",&x1,&y1,&changeto); change(x1,y1,cnum[x1][y1],changeto); cnum[x1][y1]=changeto; } } } return 0; }
真正的二维数组,果然速度快好多。
ac的代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define N 510
int bit
;
int cnum
;
int n,m;
int lowbit(int x){
return ((~x)+1)&x;
}
int query(int x,int y){
int ans=0;
for(int i=x;i;i=i-lowbit(i)){
for(int j=y;j;j=j-lowbit(j)){
ans^=bit[i][j];
}
}
return ans;
}
void change(int x,int y,int changeto){
for(int i=x;i<=n;i=i+lowbit(i)){
for(int j=y;j<=m;j=j+lowbit(j)){
bit[i][j]^=changeto;
}
}
return;
}
int main(){
int t;
int q;
int op;
int x1,y1,x2,y2;
int ans;
int changeto;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m,&q);
memset(bit,0,sizeof(bit));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&cnum[i][j]);
change(i,j,cnum[i][j]);
}
}
for(int i=0;i<q;i++){
scanf("%d",&op);
if(op==1){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
ans=query(x2,y2)^query(x1-1,y2)^query(x2,y1-1)^query(x1-1,y1-1);
if(ans==0){
printf("No\n");
}
else{
printf("Yes\n");
}
}
else{
scanf("%d%d%d",&x1,&y1,&changeto);
change(x1,y1,changeto^cnum[x1][y1]);
cnum[x1][y1]=changeto;
}
}
}
return 0;
}
相关文章推荐
- Xcode的一些使用技巧
- Linq分组
- 0921,函数 枚举
- NOI题库1799 最短前缀
- leetcode18 4sum
- 【NOIP2015 11.2上午模拟】总结
- libevent代码阅读(2)——尾队列的学习
- 黑马程序员——基础知识——面向对象
- phpmyadmin 配置文件权限错误,无法写入!
- Java资源大全中文版
- label
- 二进制中有多少个1
- 从驱动层分析android的Binder机制
- 从驱动层分析android的Binder机制-android学习之旅(83)
- 从驱动层分析android的Binder机制-android学习之旅(83)
- Linux中的静态库和动态库简介及生成过程示例
- selinux 查看 关闭
- 绑定启动Service
- 在Eclipse中使用JUnit4进行单元测试
- 从驱动层分析android的Binder机制-android学习之旅(83)