Light OJ 1080 - Binary Simulation
題目鏈接:http://www.lightoj.com/volume_showproblem.php?problem=1080
PDF (English) | problem=1080" style="color:rgb(79,107,114)">Statistics |
problem=1080" style="color:rgb(79,107,114)">Forum |
Time Limit: 2 second(s) | Memory Limit: 64 MB |
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
Output
For each case, print the case number in a single line. Then for each query ‘Q i‘
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 |
Note
Dataset is huge, use faster i/o methods.
PROBLEM SETTER: JANE ALAM JAN
題目大意:給你一段二進制數,當輸入為 I x y時。就把這段變成它的反串 。當為Q 就查詢當前x這個位置的數字視為0還是1。
思路:此題有兩種解題的思路,一種是線段樹。一種是樹狀數組。當用樹狀數組時。能夠看成是一個區間改動,單點查詢的問題,當我們用線段樹時。那麽就須要用到懶惰標記。
對於這道題樹狀數組確實比線段是快非常多。
。。。
線段樹代碼:
//time 584 ms #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<iostream> #define L(u) u<<1 #define R(u) u<<1|1 using namespace std; const int Max=100010; char str[Max]; class Node { public: int l,r; char str; int add; }node[Max*4]; void build(int l,int r,int u) { node[u].l=l; node[u].r=r; node[u].add=0; if(l==r) { node[u].str=str[l]; return; } int mid=(l+r)/2; build(l,mid,L(u)); build(mid+1,r,R(u)); } void pushdown(int u) //註意這兒要懶惰標記 { node[L(u)].add+=node[u].add; //主義要加上。。。。
。 node[R(u)].add+=node[u].add; node[u].add=0; } void update(int l,int r,int u) { if(l<=node[u].l&&node[u].r<=r) { node[u].add++; return ; } if(node[u].add) pushdown(u); int mid=(node[u].l+node[u].r)/2; if(r<=mid) { update(l,r,L(u)); } else if(l>mid) { update(l,r,R(u)); } else { update(l,mid,L(u)); update(mid+1,r,R(u)); } return ; } char query(int l,int r,int u) { if(l<=node[u].l&&node[u].r<=r) { if((node[u].add%2)==1) { node[u].add=0; if(node[u].str=='1') { node[u].str='0'; return node[u].str; } else { node[u].str='1'; return node[u].str; } } else { node[u].add=0; return node[u].str; } } if(node[u].add) pushdown(u); int mid=(node[u].l+node[u].r)/2; if(r<=mid) { return query(l,r,L(u)); } else if(l>mid) { return query(l,r,R(u)); } } int main() { int T,q,i,j,kk=0;; scanf("%d",&T); while(T--) { getchar(); kk++; str[0]='3'; scanf("%s",str+1); int len=strlen(str); build(1,len-1,1); scanf("%d",&q); char ch[5]; printf("Case %d:\n",kk); for(i=0;i<q;i++) { scanf("%s",ch); if(ch[0]=='I') { int x,y; scanf("%d%d",&x,&y); update(x,y,1); } else { int x; scanf("%d",&x); printf("%c\n",query(x,x,1)); } } } return 0; }
樹狀數組代碼:
//time 304 ms #include<cstdio> #include<cmath> #include<cstring> #include<iostream> using namespace std; const int Max=100010; int a[Max]; int n; int lowbit(int x) { return x&(-x); } void insert(int x,int d) { while(x<=n) { a[x]+=d; x+=lowbit(x); } } int query(int x) { int res=0; while(x>0) { res+=a[x]; x-=lowbit(x); } return res; } int main() { char str[Max],ch[5]; int T,q,kk=0; scanf("%d",&T); while(T--) { kk++; memset(a,0,sizeof(a)); str[0]='2'; scanf("%s",str+1); n=strlen(str)-1; scanf("%d",&q); printf("Case %d:\n",kk); for(int i=0;i<q;i++) { scanf("%s",ch); if(ch[0]=='I') { int x,y; scanf("%d%d",&x,&y); insert(x,1); insert(y+1,-1); } else { int x; scanf("%d",&x); int t=query(x); if(t%2==1) { if(str[x]=='1') { printf("0\n"); } else { printf("1\n"); } } else { printf("%c\n",str[x]); } } } } return 0; }
Light OJ 1080 - Binary Simulation