light oj 1080 線段樹和樹狀陣列
http://www.lightoj.com/volume_showproblem.php?problem=1080
Given a binary number, we are about to do some operations on the number. Two types of operations can be here.
'I i j' which means invert the bit from i to j (inclusive)
'Q i' answer whether the ith bit is 0 or 1
The MSB (most significant bit) is the first bit (i.e. i=1). The binary number can contain leading zeroes.
Input
Input starts with an integer T (≤ 10), denoting the number of test cases.
Each case starts with a line containing a binary integer having length n (1 ≤ n ≤ 105). The next line will contain an integer q (1 ≤ q ≤ 50000) denoting the number of queries. Each query will be either in the form 'I i j' where i, j are integers and 1 ≤ i ≤ j ≤ n. Or the query will be in the form 'Q i' where i is an integer and 1 ≤ i ≤ n.
Output
For each case, print the case number in a single line. Then for each query 'Q i' you have to print 1 or 0 depending on the ith bit.
Sample Input |
Output for Sample Input |
2 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 |
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=100006;
char s[maxn];
struct segementtree
{
struct Tree
{
int l,r;
char value;
int flag;
}tree[maxn*4];
void push_down(int root)
{
if(tree[root].flag)
{
tree[root<<1].flag+=tree[root].flag;
tree[root<<1|1].flag+=tree[root].flag;
tree[root].flag=0;
}
}
void build(int root,int l,int r)
{
tree[root].l=l;
tree[root].r=r;
tree[root].flag=0;
if(l==r)
{
tree[root].value=s[l];
return;
}
int mid=l+(r-l)/2;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
}
void update(int root,int l,int r)
{
if(l<=tree[root].l&&tree[root].r<=r)
{
tree[root].flag++;
return;
}
push_down(root);
int mid=tree[root].l+(tree[root].r-tree[root].l)/2;
if(l<=mid)
update(root<<1,l,r);
if(mid<r)
update(root<<1|1,l,r);
}
char query(int root,int l,int r)
{
if(l<=tree[root].l&&tree[root].r<=r)
{
if(tree[root].flag%2)
{
tree[root].flag=0;
if(tree[root].value=='1')
{
tree[root].value='0';
return tree[root].value;
}
else
{
tree[root].value='1';
return tree[root].value;
}
}
else
{
tree[root].flag=0;
return tree[root].value;
}
}
push_down(root);
int mid=tree[root].l+(tree[root].r-tree[root].l)/2;
if(l<=mid)
return query(root<<1,l,r);
else if(mid<r)
return query(root<<1|1,l,r);
}
}tr;
int main()
{
int T,n,tt=0;
scanf("%d",&T);
while(T--)
{
getchar();
scanf("%s",s+1);
int len=strlen(s+1);
//printf("%d\n",len);
tr.build(1,1,len);
scanf("%d",&n);
printf("Case %d:\n",++tt);
while(n--)
{
char c[2];
int x,y;
scanf("%s",c);
if(c[0]=='I')
{
scanf("%d%d",&x,&y);
tr.update(1,x,y);
}
else
{
scanf("%d",&x);
printf("%c\n",tr.query(1,x,x));
}
}
}
return 0;
}
2.樹狀陣列
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
const int maxn=110005;
int c[maxn],len;
int lowbit(int x)
{
return (-x)&x;
}
int sum(int x)
{
int ret=0;
while(x>0)
{
ret+=c[x];
x-=lowbit(x);
}
return ret;
}
void add(int x,int d)
{
while(x<=len)
{
c[x]+=d;
x+=lowbit(x);
}
}
int main()
{
int T,tt=0;
char s[maxn];
scanf("%d",&T);
while(T--)
{
memset(c,0,sizeof(c));
scanf("%s",s+1);
len=strlen(s+1);
int n;
scanf("%d",&n);
printf("Case %d:\n",++tt);
while(n--)
{
char a[2];
scanf("%s",a);
if(a[0]=='I')
{
int x,y;
scanf("%d%d",&x,&y);
add(x,1);
add(y+1,-1);
}
else
{
int x;
scanf("%d",&x);
int t=sum(x);
if(t&1)
{
if(s[x]=='1')
printf("0\n");
else
printf("1\n");
}
else
printf("%c\n",s[x]);
}
}
}
return 0;
}
總結:對於這種區間的查詢和修改操作,基本上都是用線段樹和數裝陣列兩種方法來進行解決,線段樹的功能要比樹狀陣列的功能要大一些,但是樹狀陣列程式碼量較小。
相關文章
- 線段樹+差分——【模板】樹狀陣列2陣列
- hdu 4836 The Query on the Tree(線段樹or樹狀陣列)陣列
- HDU 1556 Color the ball(線段樹|樹狀陣列)陣列
- 2024年暑假關於線段樹和樹狀陣列的小知識點陣列
- 樹狀陣列陣列
- 樹狀陣列和逆序對陣列
- POJ 3468 【區間修改+區間查詢 樹狀陣列 | 線段樹 | 分塊】陣列
- 【Leetcode每日一題】327. 區間和的個數(線段樹/樹狀陣列)LeetCode每日一題陣列
- 解析樹狀陣列陣列
- LeetCode C++ 劍指 Offer 51. 陣列中的逆序對【歸併排序/樹狀陣列/線段樹】LeetCodeC++陣列排序
- hdu 4368 樹狀陣列 離線維護陣列
- 樹狀陣列詳解陣列
- 樹狀陣列基礎陣列
- poj 2481 樹狀陣列陣列
- hdu 3874 樹狀陣列陣列
- 二維樹狀陣列陣列
- 樹狀陣列模板題 & (樹狀陣列 1:單點修改,區間查詢)陣列
- SPOJ DQUERY (離線數狀陣列||線上主席樹)陣列
- hdu 5147 樹狀陣列陣列
- 【筆記/模板】樹狀陣列筆記陣列
- 樹狀陣列快速入門陣列
- CF 293 E Close Vertices (樹的分治+樹狀陣列)陣列
- 樹狀陣列模板+習題集陣列
- 樹狀陣列3種基本操作陣列
- 學習筆記----樹狀陣列筆記陣列
- 樹狀陣列upc1976陣列
- CSU 4441 Necklace (樹狀陣列/LIS)陣列
- 樹狀陣列(我是真小白)陣列
- 資料結構——樹狀陣列資料結構陣列
- 線~段~樹
- 線段樹
- 數列求和【線段樹基礎】
- 10:Challenge 3(樹狀陣列直接修改)陣列
- POJ 3928 Ping pong(樹狀陣列)陣列
- 線段樹 hate it
- 【模版】線段樹
- 01 線段樹
- 線段樹--RMQMQ