博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Tyvj1474 打鼹鼠
阅读量:5335 次
发布时间:2019-06-15

本文共 3072 字,大约阅读时间需要 10 分钟。

Description

 

在这个“打鼹鼠”的游戏中,鼹鼠会不时地从洞中钻出来,不过不会从洞口钻进去(鼹鼠真胆大……)。洞口都在
一个大小为n(n<=1024)的正方形中。这个正方形在一个平面直角坐标系中,左下角为(0,0),右上角为(n-1,n-1)。
洞口所在的位置都是整点,就是横纵坐标都为整数的点。而SuperBrother也不时地会想知道某一个范围的鼹鼠总数
。这就是你的任务。

Input

每个输入文件有多行。
第一行,一个数n,表示鼹鼠的范围。
以后每一行开头都有一个数m,表示不同的操作:
m=1,那么后面跟着3个数x,y,k(0<=x,y<n),表示在点(x,y)处新出现了k只鼹鼠;
m=2,那么后面跟着4个数x1,y1,x2,y2(0<=x1<=x2<n,0<=y1<=y2<n),表示询问矩形(x1,y1)-(x2,y2)内的鼹鼠数量;
m=3,表示老师来了,不能玩了。保证这个数会在输入的最后一行。
询问数不会超过10000,鼹鼠数不会超过maxlongint。

Output

对于每个m=2,输出一行数,这行数只有一个数,即所询问的区域内鼹鼠的个数。

Sample Input

41 2 2 52 0 0 2 33

Sample Output

5

乍一看这个题目,是不是很像线段树操作,欸,这个二维平面怎么线段树啊

 

让我们来想一想,一颗线段树维护x轴,另一颗维护y轴,

 

那线段树岂不是要嵌套,那外层的线段树的每一个节点都代表1个x坐标,那么每个节点都得保存一颗线段树,那颗内层的线段树就保存y坐标;

这种数据结构就叫做二维线段树

修改操作就稍微麻烦一点了

 

要先在外层线段树中查找x坐标,再到当前x坐标保存的y坐标的线段树中去找,进行修改

提示:外层线段树是不能进行修改的!!!

1 #include
2 #include
3 #include
4 using namespace std; 5 int a,b,c,d,n,m,ans; 6 void read(int &x) { 7 char ch; bool ok; 8 for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1; 9 for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;10 }11 struct oo12 {13 int a,b;14 struct o{
int a,b,num;}y[3025];15 void build(int now,int l,int r)16 {17 y[now].a=l,y[now].b=r;18 if(l==r)return ;19 build(now<<1,l,l+r>>1);20 build(now<<1|1,(l+r>>1)+1,r);21 }22 void change(int now,int r,int num)23 {24 y[now].num+=num;25 if(y[now].a==y[now].b)return ;26 int mid=y[now].a+y[now].b>>1;27 if(r<=mid)change(now<<1,r,num);28 else change(now<<1|1,r,num);29 }30 void get(int now,int b1,int b2)31 {32 if(b1<=y[now].a&&b2>=y[now].b)33 ans+=y[now].num;34 else35 {36 int mid=y[now].a+y[now].b>>1;37 if(b1<=mid)get(now<<1,b1,b2);38 if(b2>mid)get(now<<1|1,b1,b2);39 }40 }41 }x[3025];42 void build(int now,int l,int r)43 {44 x[now].a=l,x[now].b=r;45 x[now].build(1,0,n);46 if(l==r)return ;47 build(now<<1,l,l+r>>1);48 build(now<<1|1,(l+r>>1)+1,r);49 }50 void change(int now,int l,int r,int num)51 {52 x[now].change(1,r,num);53 if(x[now].a==x[now].b)return ;54 int mid=x[now].a+x[now].b>>1;55 if(l<=mid)change(now<<1,l,r,num);56 else change(now<<1|1,l,r,num);57 }58 void get(int now,int a1,int a2,int b1,int b2)59 {60 if(a1<=x[now].a&&a2>=x[now].b)61 x[now].get(1,b1,b2);62 else63 {64 int mid=x[now].a+x[now].b>>1;65 if(a1<=mid)get(now<<1,a1,a2,b1,b2);66 if(a2>mid)get(now<<1|1,a1,a2,b1,b2);67 }68 }69 int main()70 {71 read(n);72 build(1,0,n);73 while(1)74 { 75 read(m);76 if(m==3)return 0;77 if(m==1)78 {79 read(a),read(b),read(c);80 change(1,a,b,c);81 }82 if(m==2)83 {84 read(a),read(b),read(c);read(d);85 get(1,a,c,b,d);86 printf("%d\n",ans);87 ans=0;88 }89 }90 }

 

转载于:https://www.cnblogs.com/lcxer/p/9441542.html

你可能感兴趣的文章
NYOJ458 - 小光棍数
查看>>
java中常用方法
查看>>
【Programming Clip】06、07年清华计算机考研上机试题解答(个别测试用例无法通过)...
查看>>
canvas动画
查看>>
4,7周围玩家
查看>>
关于webpack升级过后不能打包的问题;
查看>>
vue - 生命周期
查看>>
Python正则表达式
查看>>
Linux进程间通信--命名管道
查看>>
UVa 10970 - Big Chocolate
查看>>
js输出
查看>>
H5多文本换行
查看>>
HAL层三类函数及其作用
查看>>
Odoo 去掉 恼人的 "上午"和"下午"
查看>>
web@h,c小总结
查看>>
java编程思想笔记(一)——面向对象导论
查看>>
Data Structure 基本概念
查看>>
Ubuntu改坏sudoers后无法使用sudo的解决办法
查看>>
NEYC 2017 游记
查看>>
[搬运] 写给 C# 开发人员的函数式编程
查看>>