hrbust/哈理工oj 1867 小伙伴的数据结构【树状数组】
来源:互联网 发布:网络新媒体专业课程 编辑:程序博客网 时间:2024/06/07 04:46
给你一些二进制串,我们有对这些数有两种操作。
'I i j' 将[i,j]内的所有数取反(0变1,1变0)
'Q i' 输出第i个数是多少
下标从1开始,输入串允许有前导0
输入包含一个整数T(T<=10000),表示测试样例个数。
每组样例的第一行有一个长度为n的01串(n<=20000)
第二行有一个整数Q(Q<=10000)代表将会有多少个操作
输出每一个Q i的结果
Sample Input2
0011001100
6
I 1 10
I 2 7
Q 2
Q 1
Q 7
Q 5
1011110111
6
I 1 10
I 2 7
Q 2
Q 1
Q 7
Q 5
Case 1:
0
1
1
0
Case 2:
0
0
0
1
思路:
1、首先看到时间限制500ms,看到Q查询次数比较大,再看题干中的两种操作,区间更新+单点查询,无疑需要使用树状数组或者是线段树之类的来优化查询和更新的操作。
2、对于取反操作,如果能够知道当前这个位子一共改变了多少次,其实也就能知道现在这个位子上的数字是几,如果改变了偶数次,那么这个位子上的数字不变,否则取反。
3、对于统计这个位子一共改变了多少次,归根到底是对于区间更新的操作的一种统计,辣么如何进行区间更新呢?如果您使用的是线段树来解,这里就可以跳过了,直接区间更新+懒惰标记即可。如果您使用的是树状数组来解,这里不难理解:
假设原串是:
01010101;
假设有一种操作,I 1 5表示对【1,5】取反,假设我们有一个数组a【8】,表示每个位子都操作了多少次,暴力情况下,我们使得:a【1】=a【2】=a【3】=a【4】=a【5】=1;对于每个点都进行一次操作,其实我们不妨优化把一堆值更新优化到两个值更新:a【1】=1;a【6】=-1;这样,假设我们询问4号位子上一共改变了多少次的时候,我们可以从a【1】+a【】...+a【4】来查询4号位子上有多少次操作,显然值为1,没有问题。那么我们要询问7号位子上一共改变了多少次的时候,我们照旧a【1】+a【2】+...+a【7】来查询7号位子上有多少次操作,显然值为0,也没有问题。这样我们就可以用树状数组来完成这两个操作了,区间值加和查询+点更新值。
4、处理好字符串,问题就解决了。
AC代码:
#include<stdio.h>#include<string.h>using namespace std;char tmp[20050];int a[20050];int tree[1000005];//树int n;int lowbit(int x)//lowbit{ return x&(-x);}int sum(int x)//求和求的是比当前数小的数字之和,至于这里如何实现,很简单:int sum=sum(a[i]);{ int sum=0; while(x>0) { sum+=tree[x]; x-=lowbit(x); } return sum;}void add(int x,int c)//加数据。{ while(x<=n) { tree[x]+=c; x+=lowbit(x); }}int main(){ int t; int kase=0; scanf("%d",&t); while(t--) { memset(tree,0,sizeof(tree)); scanf("%s",tmp); n=strlen(tmp); for(int i=1;i<=n;i++) { a[i]=tmp[i-1]-'0'; } int q; scanf("%d",&q); printf("Case %d:\n",++kase); while(q--) { char op[5]; scanf("%s",op); if(op[0]=='Q') { int x; scanf("%d",&x); int cishu=sum(x); //printf("%d\n",cishu); if(cishu%2==0) { printf("%d\n",a[x]); } else printf("%d\n",1-a[x]); } else { int x,y; scanf("%d%d",&x,&y); add(x,1); add(y+1,-1); } } }}
- hrbust/哈理工oj 1867 小伙伴的数据结构【树状数组】
- hrbust 1625 哈理工oj ikki的数字【树状数组】
- hrbust 2046 哈理工oj 2046 最后的题目八个字【二维树状数组】
- hrbust 2234 哈理工oj 逆序对问题【树状数组+离散化】
- hrbust 2132 哈理工oj 2132 数方格【二维树状数组】
- hrbust 哈理工oj 1176 小陈老师、雪人(优先队列)
- Hrbust oj/哈理工 oj 1216数的划分
- hrbust 哈理工oj 2181 无聊的小明【数位DP】
- 哈理工oj hrbust 2267 从前的运算符【思维】
- hrbust 1216/哈理工oj 1216 数的划分【dp】
- hrbust/哈理工oj 1475国王的宴会【树型dp】
- hrbust 哈理工oj 1588 神医【贪心】
- hrbust 哈理工oj 网线【MST+Prim】
- 哈理工oj/hrbust 1790 武林【DP】
- hrbust哈理工oj 1674 充电【贪心】
- hrbust 哈理工oj 1330 邂逅【模拟】
- hrbust/哈理工oj 1877 区间【水题】
- hrbust 1424 哈理工oj 1424 Hrbust的校车【水题】【思维】
- codeforces 675A Infinite Sequence
- 199. Binary Tree Right Side View
- Java图形界面开发—列出指定目录
- 设计模式之原型模式
- C#当前日期时间
- hrbust/哈理工oj 1867 小伙伴的数据结构【树状数组】
- 网络流二十四题之十一 —— 航空路线问题(AIRL)
- 数组—— 2 sum, 3 sum, 3 sum closed, 4Sum.
- 华为在线训练之字符串分隔
- qsys初探————中断注册API
- 【LeetCode-105】Construct Binary Tree from Preorder and Inorder Traversal
- 慕课网二次学习(二)
- 可视化篇:Echarts个人轨迹可视化实现
- 博客新地址