异或问题

异或的作用:0+1=1 ,0+0=0或者1+1=0
输入描述:
第一行一个数字n
第二行n个数字

输出描述:
输出最多的区间的个数

示例:
输入
3 0 2 2

输出
2
思路:因为每两个数之间异或的值我们无法判断,所以采用一个思想:我先给定一个值(’存入set集合。其他集合都行)然后将它与后一个数异或(’存入set集合),再将值与后一位数异或(’存入set集合),以此类推,直到某一个结果与之前的值相等,那么此时count加一。 只要中间有值异或为0,那么就肯定 会有后来的值等于之前的值。

public class Solution4 {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int res=0;
        int i=0;
        int count=0;
        Set<Integer> mSet=new HashSet<>();
        mSet.add(res);
        while(i<n) {
            res=res^(sc.nextInt());
            if(mSet.contains(res)) {
                count++;
                mSet.clear();
            }
            mSet.add(res);
            i++;
        }
        System.out.println(count);
    }
}

题目描述:给定整数m以及n个数字A1, A2, …, An,将数列A中所有元素两两异或,共能得到n(n-1)/2个结果。
请求出这些结果中大于m的有多少个。
输入:第一行包含两个整数n, m。
第二行给出n个整数A1, A2, …, An。
样例输入:3 10
6 5 10
输出:输出仅包括一行,即所求的答案。
样例输出:2

异或那道题可以把每个数的二进制位求出来,用一个字典树维护,然后遍历每一个数按位贪心,比如这一位m是1,遍历的这个数这一位是0,那么和他异或的数就必须是1,如果这一位m是0,要大于m的话异或和的这一位可以是1也可以是零,ans加上之前维护的二进制位加上使这一位为1的数在字典树中查询有多少个数满足这个前缀的条件,然后在令这一位的异或和为0,继续向下遍历,最后的答案除以2。


image.png
import java.util.Scanner;
 
public class Q2_异或 {
    public static void main(String[] args) {
        trieNode root = new trieNode(-1);//根节点不存有效值
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int[] items = new int[n];
        for(int i=0; i<n; i++){
            items[i] = sc.nextInt();
            insert(root, items[i]);
        }
        long result = 0;
        for(int num : items){
            result  += query(root, num, m, 31);//31到0是整数能表示的范围
        }
        System.out.println(result/2);
    }
 
    /**
     * 将number加入到root中
     * @param root
     * @param number
     */
    public static void insert(trieNode root, int number){
        trieNode current = root;
        for(int i=31; i>=0; i--){//先存放高位数字比如数字5,二进制为0101,则存放顺序是0,1,0,1
            //求解对应第i位置处二进制数字是0还是1
            int digit = (number>>i)&1;
            if(current.next[digit]==null){
                current.next[digit] = new trieNode(digit);
            }
            current = current.next[digit];
            current.count++;
        }
    }
    
    /**
     * @param root//trieTree树
     * @param a//a是做异或运算的其中的一个值
     * @param m//和异或结果进行比较的数字,大于m记录值加1
     * @param k//number转换为二进制后对应的第k位置上的数字
     * @return
     */
    public static int query(trieNode root, int a, int m, int k){
        if(root == null){
            return 0;
        }
        trieNode current = root;
        for(int i=k; i>=0; i--){
            int aDigit = (a>>i)&1;
            int mDigit = (m>>i)&1;
            if(aDigit == 1 && mDigit == 1){
                if(current.next[0] == null){//对应k位置处的数字若为空,则返回0
                    return 0;
                }else{
                    current = current.next[0];//返回第k位置为0的数字的个数
                }
            }else if(aDigit == 0 && mDigit ==1){
                if(current.next[1] == null){
                    return 0;
                }else {
                    current = current.next[1];
                }
            }else if(aDigit == 0 && mDigit == 0){
                int p = query(current.next[0], a, m, i-1);
                int q = (current.next[1]==null?0:current.next[1].count);
                return p+q;
            }else if(aDigit == 1 && mDigit == 0){
                int p = query(current.next[1], a, m, i-1);
                int q = (current.next[0]==null?0:current.next[0].count);
                return p+q;
            }
        }       
        return 0;
    }   
}
 
//存放所有数字的二进制的形式的trie树
class trieNode{
    trieNode[] next = new trieNode[2];//存放孩子结点,只有0和1两种数字
    int count = 0;//此处包含的数字0或1的个数
    int digit = 0;
    public trieNode(int digit) {
        this.digit = digit;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,277评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,689评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,624评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,356评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,402评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,292评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,135评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,992评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,429评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,636评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,785评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,492评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,092评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,723评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,858评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,891评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,713评论 2 354

推荐阅读更多精彩内容