• Codeforces Round #539 (Div. 2) C. Sasha and a Bit of Relax


    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    #include <map>
    #include <cstdlib>
    #include <vector>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int maxn = 3e5 + 100;
    ll pre[maxn], a[maxn];
    int num[(1 << 20) + 100][2];
    int main()
    {
    	int n,cnt=1;
    	cin >> n;
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%I64d", &a[i]);
    		pre[i] = pre[i - 1] ^ a[i];
    	}
    	num[0][0] = 1;
    	ll ans = 0;
    	for(int i=1;i<=n;i++)
    	{
    		ans += num[pre[i]][i & 1];
    		num[pre[i]][i & 1]++;
    	}
    	printf("%I64d
    ", ans);
    	return 0;
    }
    

      

    C. Sasha and a Bit of Relax
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Sasha likes programming. Once, during a very long contest, Sasha decided that he was a bit tired and needed to relax. So he did. But since Sasha isn't an ordinary guy, he prefers to relax unusually. During leisure time Sasha likes to upsolve unsolved problems because upsolving is very useful.

    Therefore, Sasha decided to upsolve the following problem:

    You have an array aa with nn integers. You need to count the number of funny pairs (l,r)(l,r) (lr)(l≤r) . To check if a pair (l,r)(l,r) is a funny pair, take mid=l+r12mid=l+r−12 , then if rl+1r−l+1 is an even number and alal+1amid=amid+1amid+2aral⊕al+1⊕…⊕amid=amid+1⊕amid+2⊕…⊕ar , then the pair is funny. In other words, ⊕ of elements of the left half of the subarray from ll to rr should be equal to ⊕ of elements of the right half. Note that ⊕ denotes the bitwise XOR operation.

    It is time to continue solving the contest, so Sasha asked you to solve this task.

    Input

    The first line contains one integer nn (2n31052≤n≤3⋅105 ) — the size of the array.

    The second line contains nn integers a1,a2,,ana1,a2,…,an (0ai<2200≤ai<220 ) — array itself.

    Output

    Print one integer — the number of funny pairs. You should consider only pairs where rl+1r−l+1 is even number.

    Examples
    Input
    Copy
    5
    1 2 3 4 5
    Output
    Copy
    1
    Input
    Copy
    6
    3 2 2 3 7 6
    Output
    Copy
    3
    Input
    Copy
    3
    42 4 2
    Output
    Copy
    0
    Note

    Be as cool as Sasha, upsolve problems!

    In the first example, the only funny pair is (2,5)(2,5) , as 23=45=12⊕3=4⊕5=1 .

    In the second example, funny pairs are (2,3)(2,3) , (1,4)(1,4) , and (3,6)(3,6) .

    In the third example, there are no funny pairs.

    这是一个异或问题,而且又有连续的一段进行异或,而异或有很多运算法则,我觉得很重要的就是交换律,所以这个可以用前缀和进行存储。

    异或运算法则:

    . a ⊕ a = 0
    2. a ⊕ b = b ⊕ a
    3. a ⊕b ⊕ c = a ⊕ (b ⊕ c) = (a ⊕ b) ⊕ c;
    4. d = a ⊕ b ⊕ c 可以推出 a = d ⊕ b ⊕ c.
    5. a ⊕ b ⊕ a = b.

    这些就可以说明要求题目中的:al^al+1^...amid=amid+1^...ar;就可以转化成:pre[l-1]^pre[mid]=pre[mid]^pre[r],这个可以由上面的异或运算法则求出。

    中间的pre[mid]可以约去,所以就是求pre[l-1]=pre[r]

    接下来求这个pre[l-1]=pre[r]的方法是我上网查的,我觉得挺好的,就是:

    用一个二维数组来存储,要求l到r之间所有数的个数为偶数,则必须是同为奇数或者同为偶数,意识到这个之后,二维数组的第二位可以设置成2,然后再看一维数组。

    进行异或,则异或之后的值不会比2的20次方还大,因为这个数最多只有20位,所以就算这个二进制的二十位都是1,也差不多就是2的20次方左右。

    所以一维数组的大小可以设置成2的20次方。

    如果之后有数是和pre[i]一样,则之后会进行累加。

    这个方法我觉得挺好的,可以用到别的题目上。

    这个题目考了:异或,前缀和,还有就是怎么去求一段集合数目是偶数,且异或值一样的集合数量。

  • 相关阅读:
    HDU1864--01背包
    HDU4508--完全背包
    HDU5410--01背包+完全背包
    HDU1284--完全背包
    HDU1248--完全背包
    HDU2191--多重背包(二进制分解+01背包)
    HDU2186--水
    PAT乙级--1003
    51Nod--1006 lcs
    51Nod--1008
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/10539563.html
Copyright © 2020-2023  润新知