[CQOI2006] 简单题 - 线段树/树状数组
来源:互联网 发布:李明linux 编辑:程序博客网 时间:2024/06/11 01:48
题目描述
有一个n个元素的数组,每个元素初始均为0。有m条指令,要么让其中一段连续序列数字反转——0变1,1变0(操作1),要么询问某个元素的值(操作2)。例如当n=20时,10条指令如下:
输入格式
第一行包含两个整数n,m,表示数组的长度和指令的条数,以下m行,每行的第一个数t表示操作的种类。若t=1,则接下来有两个数L, R (L<=R),表示区间[L, R]的每个数均反转;若t=2,则接下来只有一个数I,表示询问的下标。
输出格式
每个操作2输出一行(非0即1),表示每次操作2的回答
样例数据
样例输入
20 10
1 1 10
2 6
2 12
1 5 12
2 6
2 15
1 6 16
1 11 17
2 12
2 6
样例输出
1
0
0
0
1
1
说明
50%的数据满足:1<=n<=1,000,1<=m<=10,000
100%的数据满足:1<=n<=100,000,1<=m<=500,000
题目分析
线段树 区间修改查询点
或
树状数组
模板题+1
源代码
线段树
#include<algorithm>#include<iostream>#include<iomanip>#include<cstring>#include<cstdlib>#include<vector>#include<cstdio>#include<cmath>#include<queue>using namespace std;inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { num=num*10+x-'0'; x=getchar(); } return num*bj;}const int maxn=100000;struct Tree { //修改区间 查询点 int left,right,data;};struct Segment_Tree { //执行加法mod2操作 Tree tree[maxn*4]; int sum; void build(int index,int Left,int Right) { tree[index].left=Left; tree[index].right=Right; tree[index].data=0; if(Left==Right)return; int mid=(Left+Right)/2; build(2*index,Left,mid); build(2*index+1,mid+1,Right); } void increase(int index,int Left,int Right,int delta) { //增加区间的值 if(Right<tree[index].left||Left>tree[index].right)return; //不相交 if(Left<=tree[index].left&&Right>=tree[index].right) { //完全包含 tree[index].data+=delta; return; } increase(index*2,Left,Right,delta); increase(index*2+1,Left,Right,delta); } void init() { //注意多次询问一定要调用 sum=0; } void Query(int index,int target) { //查询点值 if(target<tree[index].left||target>tree[index].right)return; //不相交 if(target>=tree[index].left&&target<=tree[index].right)sum+=tree[index].data; //完全包含 if(tree[index].left==tree[index].right)return; Query(index*2,target); Query(index*2+1,target); }};Segment_Tree st;int n,m;int main() { n=Get_Int(); m=Get_Int(); st.build(1,1,n); for(int i=1; i<=m; i++) { int order=Get_Int(); if(order==1) { int Left=Get_Int(),Right=Get_Int(); st.increase(1,Left,Right,1); } else { int target=Get_Int(); st.init(); st.Query(1,target); printf("%d\n",st.sum%2); } } return 0;}
树状数组
#include<algorithm>#include<iostream>#include<iomanip>#include<cstring>#include<cstdlib>#include<vector>#include<cstdio>#include<cmath>#include<queue>using namespace std;int n,m,f[100005];inline const int Get_Int() { int n=0,bj=1; char x=getchar(); while(x<'0'||x>'9') { if(x=='-')bj=-1; x=getchar(); } while(x>='0'&&x<='9') { n=n*10+x-'0'; x=getchar(); } return n*bj;}int Lowbit(int x) { return x&-x;}void Add(int x,int d) { for(int i=x; i<=n; i+=Lowbit(i))f[i]+=d;}int Ask(int r) { int sum=0; for(int i=r; i>=1; i-=Lowbit(i))sum+=f[i]; return sum;}int main() { n=Get_Int(); m=Get_Int(); for(int i=1; i<=m; i++) { int order=Get_Int(); if(order==1) { int x=Get_Int(),y=Get_Int(); Add(x,1); Add(y+1,-1); } else { int x=Get_Int(); printf("%d\n",Ask(x)%2); } } return 0;}
0 0
- [CQOI2006] 简单题 - 线段树/树状数组
- 线段树,树状数组
- 线段树,树状数组
- 线段树,树状数组
- 线段树,树状数组
- 树状数组-线段树
- 线段树 && 树状数组
- 线段树,树状数组
- 线段树&&树状数组
- 线段树+树状数组
- [NOIP模拟题][树状数组][线段树]
- zoj 3349 简单DP 线段树或树状数组优化
- HDU 1166 敌兵布阵 【简单的树状数组||线段树】
- 树状数组和线段树
- 线段树and树状数组
- 线段树+树状数组整理
- 线段树、树状数组问题
- 线段树与树状数组
- 我们的专利在哪里?
- (Linux)IP地址配置
- JSON工具(org.json)
- JavaScript字符集编码与解码_1
- Elasticsearch mappings小结
- [CQOI2006] 简单题 - 线段树/树状数组
- driveddate的清除路径
- 求两个数组的最长公共子串长度(LCS)
- 未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包导致的此版本的应用程序不支持其项目类型(.vcproj)的解决办法
- 2.输入5个数(含负数、小数)将它们按由小到大的顺序排列起来
- 使用迅雷下载百度云盘大文件方法
- Discuz 门户列表页自动获取内容图片
- recyclerView多条目展示,ArgbEvaluator颜色渐变
- String、StringBuffer与StringBuilder之间区别