3年没写线段树题了,今天帮小学弟水了棵线段树,想不到现在依然有看到Accepted的鸡冻哈哈哈
2016-04-26 21:34
393 查看
题目大意:给一个区间1~10^10,然后Q个操作有更新,有询问,Q的范围是1~10^5,明显是一个离散化+区间更新的线段树水题传送门,这里更新需要注意lay的思想,也就是延迟更新,具体就是push down和push up操作,具体看代码;
#include <cstdio> #include <algorithm> #include <iostream> using namespace std; const int MAX=204002; int a[MAX*2]; int op[MAX][3]; struct node{ int l,r,ok; }tree[MAX*8]; void build(int pos,int l,int r) { tree[pos].l=l; tree[pos].r=r; tree[pos].ok = a[tree[pos].r-1] - a[tree[pos].l-1]+1; if(l==r) return; int mid=(l+r)>>1; build(pos*2,l,mid); build(pos*2+1,mid+1,r); tree[pos].ok = tree[pos*2].ok+ tree[pos*2+1].ok; } void update(int pos,int l,int r){ if(l<=tree[pos].l&&tree[pos].r<=r) { tree[pos].ok = 0; return; } if(tree[pos].ok==0) { //lay :push down tree[pos*2].ok = 0; tree[pos*2+1].ok = 0; } int mid=(tree[pos].l+tree[pos].r)>>1; if(r<=mid) update(pos*2,l,r); else if(l>mid) update(pos*2+1,l,r); else { update(pos*2,l,mid); update(pos*2+1,mid+1,r); } tree[pos].ok = tree[pos*2].ok + tree[pos*2+1].ok; //lay : push up } int query(int pos,int l,int r){ if(l<=tree[pos].l&&tree[pos].r<=r) { return tree[pos].ok; } int mid=(tree[pos].l+tree[pos].r)>>1; if(tree[pos].ok==0) { tree[pos*2].ok = 0; tree[pos*2+1].ok = 0; } if(r<=mid) return query(pos*2,l,r); else if(l>mid) return query(pos*2+1,l,r); else { return query(pos*2,l,mid)+ query(pos*2+1,mid+1,r); } } int main(){ int N,Q; cin>>N>>Q; int index = 0; for(int i=0;i<Q;i++) { scanf("%d%d%d",&op[i][0],&op[i][1],&op[i][2]); a[index++]=op[i][1]; a[index++]=op[i][2]; } //两次离散化,防止有相邻的数据 sort(a,a+index); int n=unique(a,a+index)-a; int t = 0; for(int i=1;i<n;i++){ if(a[i]-a[i-1]!=1){ a[n+t] = a[i-1]+1; t++; } } sort(a,a+n+t); n=unique(a,a+n+t)-a; build(1,1,n); for(int i=0;i<Q;i++) { if(op[i][0]==1) { update(1, lower_bound(a,a+n,op[i][1])-a+1 , lower_bound(a,a+n,op[i][2])-a+1 ); }else { printf("%d\n",query(1, lower_bound(a,a+n,op[i][1])-a+1, lower_bound(a,a+n,op[i][2])-a+1 )); } } return 0; }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性