Light OJ 1080 - Binary Simulation

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1080

1080 - Binary Simulation

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). 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

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;
}
时间: 2024-12-13 01:14:19

Light OJ 1080 - Binary Simulation的相关文章

Light OJ 1080 - Binary Simulation - (线段树区间更新 单点查询)

Description 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 signif

1080 - Binary Simulation

   PDF (English) Statistics 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)

light oj 1236 【大数分解】

给定一个大数,分解质因数,每个质因子的个数为e1,e2,e3,--em, 则结果为((1+2*e1)*(1+2*e2)--(1+2*em)+1)/2. //light oj 1236 大数分解素因子 #include <stdio.h> #include <iostream> #include <string.h> #include <algorithm> #include <math.h> #include <ctype.h> #i

[2016-04-21][light]OJ[1234][Harmonic Number]

时间:2016-04-21 22:18:26 星期四 题目编号:[2016-04-21][light]OJ[1234][Harmonic Number] 题目大意:求∑nk=11kn∈(1,108),精确到10?8求∑k=1n1kn∈(1,108),精确到10?8 分析: 想法是打表,然后输出,但是直接打表会爆内存 解决办法,就是每隔100个来打表,节省1100的空间,然后从那个值开始计算到当前值解决办法,就是每隔100个来打表,节省1100的空间,然后从那个值开始计算到当前值 对应的整百就是n

Light OJ 1411 Rip Van Winkle`s Code 线段树成段更新

题目来源:Light OJ 1411 Rip Van Winkle`s Code 题意:3中操作 1种查询 求区间和 其中每次可以把一段区间从左到右加上1,2,3,...或者从右到左加上...3,2,1 或者把某个区间的数都置为v 思路:我是加了6个域 add是这段区间每个数都要加上add  add是这么来的 对与123456...这个等差数列 可能要分为2个区间 那么我就分成123和123 两个右边的等差数列每个数还应该加上3 所以右区间add加3 v是这个区间都要置为v 他的优先级最高 b是

LeetCode OJ - Balanced Binary Tree

判断树是否是平衡的,这道题中的平衡的概念是指任意节点的两个子树的高度相差不超过1,我用递归的方法把所有的节点的高度都计算了下,并且在计算的过程记录每个节点左右两颗子树的高度差,最后通过遍历这个高度差就可以知道是否是平衡的. 下面是AC代码: 1 /** 2 * Given a binary tree, determine if it is height-balanced. 3 * For this problem, a height-balanced binary tree is defined

Light OJ 1168 Wishing Snake 强连通缩点+哈密顿通路

题目来源:Light OJ 1168 Wishing Snake 题意:有点难看懂题意 看了一个小时再加别人的代码才懂意思 从0开始 输入的那些每一对u v 都要经过 就是从0到到达那些点 思路:首先缩点 每一个强连通分量里面的点都是可达的 缩点后的图是有向无环图 如果从0这个强连通分量可以出去到2个强连通分量 那么这两个强连通分量是不可能相互可达 所以可行的方案就是所有的强连通分量连成一线 一个一个串起来 除了第一个 出度是1入度是0和最后一个出度是0入度是1 其他都是入度等于出度是1 特判只

LeetCode OJ - construct Binary Tree from Inorder and Postorder/Preorder Traversal

不断递归的实现!!!! 下面是AC代码: 1 /** 2 * Given inorder and postorder traversal of a tree, construct the binary tree. 3 * @param inorder 4 * @param postorder 5 * @return 6 */ 7 public TreeNode buildTree(int[] inorder,int[] postorder){ 8 if(inorder == null || po

Jan&#39;s light oj 01--二分搜索篇

碰到的一般题型:1.准确值二分查找,或者三分查找(类似二次函数的模型). 2.与计算几何相结合答案精度要求比较高的二分查找,有时与圆有关系时需要用到反三角函数利用 角度解题. 3.不好直接求解的一类计数问题,利用二分直接枚举可能的结果,再检查是否符合题目要求. 4.区间求解,即利用两次二分分别查找有序序列左右上下限,再求差算出总个数. 题型知识补充: 1. 三分的一般写法: 1 double thfind(double left,double right) 2 { 3 double midmid