zoukankan      html  css  js  c++  java
  • NC14247—Xorto—(位运算+前缀和)

    https://ac.nowcoder.com/acm/problem/14247

    题目描述

    给定一个长度为 nnn 的整数数组,问有多少对互不重叠的非空区间,使得两个区间内的数的异或和为 000。

    输入描述

    第一行一个数 nnn 表示数组长度;
    第二行 nnn 个整数表示数组; 1≤n≤10001leq nleq 10001n1000,0≤数组元素<1000000leq 数组元素 lt1000000<100000。

    输出描述

    一行一个整数表示答案。

    示例1

    输入

    3
    0 0 0

    输出

    5

    说明

    ([1,1],[2,2]),([1,1],[3,3]),([1,1],[2,3]),([1,2],[3,3]),([2,2],[3,3])

    思路:位运算,还是区间,考虑前缀和。

    求不相互覆盖的两个区间异结果相同,假设[x,y]是右区间 异结果 是z,只要考虑左边区间有多少个异结果为z,一一对应即可。桶排序的思想,用一个计数数组计算左边区间的各个 异结果 有多少个。遍历数组中,以i为分割点,[l,i]和[i+1,r],暴力l和r,累计左边区间对右边区间的贡献。[l,i]的区间异结果为b[l-1]^b[i],相当于把[1,l-1]异两次,那就成0了。

    import java.math.BigDecimal;
    import java.math.BigInteger;
    import java.awt.Checkbox;
    import java.io.BufferedInputStream;
    import java.util.*;
    public class Main{
        
        public static void main(String []args) {
            Scanner scan=new Scanner(System.in);
            int[] a=new int[10005];
            int[] b=new int[10005];///异 前缀和
            long[] num=new long[1000086];///左边 异结果 计数
            long ans=0;
            int n=scan.nextInt();
            for(int i=1;i<=n;i++) {
                a[i]=scan.nextInt();
                b[i]=b[i-1]^a[i];
            }
            for(int i=1;i<=n;i++){//求左右区间的个数,因为不重叠,i包括在左边里,不包括在右边
                // 1 2 3 4 5
                for(int l=1;l<=i;l++) {
                    int x=b[l-1]^b[i];
                    num[x]++;
                }
                for(int r=i+1;r<=n;r++) {
                    int x=b[i]^b[r];
                    ans+=num[x];
                }
            }
            System.out.println(ans);
        }
    }
  • 相关阅读:
    Word Puzzles [POJ 1204]
    set用法
    FOJ有奖月赛2012年11月
    BerDonalds
    POJ1469 匈牙利算法
    后缀数组
    ZOJ Monthly, January 2013
    算法导论<一>
    Yell Classico
    点聚 WebOffice 编辑辅助控件 WebOffice.OCX
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/12712244.html
Copyright © 2011-2022 走看看