题目描述
给定整数m以及n各数字A1,A2,..An,将数列A中所有元素两两异或,共能得到n(n-1)/2个结果,请求出这些结果中大于m的有多少个。
输入描述:
第一行包含两个整数n,m.
第二行给出n个整数A1,A2,...,An。
数据范围
对于30%的数据,1 <= n, m <= 1000
对于100%的数据,1 <= n, m, Ai <= 10^5
输出描述:
输出仅包括一行,即所求的答案
示例1
输入
复制
3 10
6 5 10
输出
复制
2
PrintWriter out=new PrintWriter(System.out);在数据多的时候效率更快,因为把数据先放到缓冲。
记得out.close();
链接:https://www.nowcoder.com/questionTerminal/fc05f68c5f47438db54c6923ef23cf4a?toCommentId=2515620
来源:牛客网
//字典树,比较一棵树等于比较多个子串,大大减少了冗余比较,在字典树节点中记录
//分枝中0,1的数量,对于每个串先比较再插入。虽然开始想到字典树了,但此题注意细节较多。
//所以好多次才过
import java.util.Scanner;
public class Main{
static class Trie{
Trie[] chi=new Trie[2];
int[] cnt=new int[2];
}
public static void main(String[] arg){
Trie root=new Trie();
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int m=sc.nextInt();
long count=0;
while(sc.hasNext()){
int num=sc.nextInt();
Trie cur=root;
for(int i=20;cur!=null&&i>=0;i--){
int a=1&(m>>i);
int b=1&(num>>i);
if(a==0&&b==0) count+=cur.cnt[1];
if(a==0&&b==1) count+=cur.cnt[0];
cur=cur.chi[a^b];//b^x=a,->b^a=x
}
cur=root;
for(int i=20;i>=0;i--){
int b=1&(num>>i);
if(cur.chi[b]==null) cur.chi[b]=new Trie();
cur.cnt[b]++;
cur=cur.chi[b];
}
}
System.out.println(count);
}
}