在[L,R]范围内查询

时间:2015-10-01 06:04:41

标签: algorithm data-structures tree

给定二进制字符串(即仅包含0和1的字符串)。他们应该对字符串执行两种类型的查询。Problem

类型0:给定两个索引l和r.Print二进制字符串的值从l到r modulo 3.

类型1:给定索引l当且仅当该索引处的值为0时,才会翻转该索引的值。

我正在尝试使用 BIT 解决此问题。

如果范围[l,r]中的数字均为,则:
如果一个数字的总和是偶数则答案为0,否则为2

如果范围[l,r]中的数字是奇数
如果一个数字的总和是偶数,则答案为0,否则为1

但是对于某些测试用例,我的答案是错误的。

public static void update(int i){

    while(A.length>i){
        A[i]+=1;
        i+=i&-i;
    }

}

public static int ans(int i){
    int a=0;

    while(i>0){
        a+=A[i];
        i-=i&-i;
    }
    return a;
}

回答每个查询。

while(Q>0){
    Q--;
    int x = in.nextInt();
    int l = in.nextInt()+1;
    if(x==1){
        if((ans(l)-ans(l-1))==0) update(l);

        continue;
    }
    int r  = in.nextInt()+1;

    int f = ans(r) - ans(r-1);

    if(f==0){

        int sum = ans(r)- ans(l-1);
        if(sum%2==0) System.out.println(0);
        else System.out.println(2);
    }else{

        int sum = ans(r)- ans(l-1);
        if(sum%2==0) System.out.println(0);
        else System.out.println(1);

    }
}

Full CODE

1 个答案:

答案 0 :(得分:0)

当构建二进制数时,从左数字到右数字,如果只考虑当前解析的字符串部分,则它是二进制数。我们称之为n。

当你在n的右边追加一个数字时,它会向左移动,然后也会添加数字(1或0)。所以n0 = 2 * n且n1 = 2 * n + 1

因为你只关心模3的数字,所以你可以跟踪这个模3。

你可以注意到

0 (mod 3) * 2     = 0 (mod 3)
0 (mod 3) * 2 + 1 = 1 (mod 3)
1 (mod 3) * 2     = 2 (mod 3)
1 (mod 3) * 2 + 1 = 0 (mod 3)
2 (mod 3) * 2     = 1 (mod 3)
2 (mod 3) * 2 + 1 = 2 (mod 3)

您可以构造一个简单的fsm来表示这些关系,并简单地使用您感兴趣的字符串部分作为输入。或者按照你想要的方式实现它。

希望您意识到“当且仅当索引的值为0时,索引l才会翻转该索引的值。”只是意味着将值设置为l为1。