zoukankan      html  css  js  c++  java
  • #trie#A 区间异或

    题目

    给定一个长度为(n)的序列,询问有多少个((l,r),1leq lleq rleq n)满足

    [xor_{lleq jleq r}a_jgeq k ]


    分析

    显然跑一次前缀和就变成查询两个数的异或值是否不少于(k)
    那么这显然可以转换成01trie的问题
    按照二进制位处理,分类讨论:

    1. 当前(x)(k)的二进制位为1,那么跳到(trie[p][0])
    2. 当前(x)(k)的二进制位为0,那么只要让该二进制位为1就能使异或值大于(k),然后累计答案再跳到(trie[p][0])
    3. 当前(x)的二进制位为0,(k)的二进制位为1,那么跳到(trie[p][1])
    4. 当前(x)的二进制位为1,(k)的二进制位为0,那么只要让该二进制位为0就能使异或值大于(k),然后累计答案再跳到(trie[p][1])

    代码

    #include <cstdio>
    #include <cctype>
    #define rr register
    using namespace std;
    const int N=1000011;
    int a[N],n,m; long long ans;
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    struct Trie{
    	int trie[N*30][2],cnt[N*30],tot;
    	inline void Clear(){
    		trie[1][0]=trie[1][1]=cnt[1]=0,tot=1;
    	}
    	inline void Insert(int x){
    		rr int p=1;
    		for (rr int i=29;~i;--i){
    			rr int z=(x>>i)&1;
    			if (!trie[p][z]){
    				trie[p][z]=++tot,cnt[tot]=0,
    				trie[tot][0]=trie[tot][1]=0;
    			}
    			++cnt[p],p=trie[p][z];
    		}
    		++cnt[p];
    	}
    	inline signed query(int x){
    		rr int p=1,ans=0;
    		for (rr int i=29;~i;--i){
    			if (!p) return ans;
    			if ((x>>i)&1){
    				if ((m>>i)&1) p=trie[p][0];
    				    else ans+=cnt[trie[p][0]],p=trie[p][1];
    			}else{
    				if ((m>>i)&1) p=trie[p][1];
    				    else ans+=cnt[trie[p][1]],p=trie[p][0];
    			}
    		}
    		return ans+cnt[p];
    	}
    }trie;
    signed main(){
    	freopen("xor.in","r",stdin);
    	freopen("xor.out","w",stdout); 
    	for (rr int T=iut();T;--T){
    		trie.Clear(),trie.Insert(0),
    		n=iut(),m=iut(),ans=0;
    		for (rr int i=1,x=0;i<=n;++i){
    			x^=iut(),
    			ans+=trie.query(x),
    			trie.Insert(x);
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    } 
    
  • 相关阅读:
    (十)安装YAML
    (十四)日志
    Android自动化测试------monkeyrunner(六)
    Android自动化测试------monkey日志管理(五)
    如何学好一门编程语言
    linux vi hjkl由来
    .net 微服务CICD 好文章
    APPCMD 精心整理 有点赞的吗
    APPCMD 命令合集
    APPCMD 使用手册
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13914804.html
Copyright © 2011-2022 走看看