备战蓝桥杯---0/1Trie模板

最近学校作业有点多+被迫参加学校的仪仗队当帕鲁,有许多题还没有补(尤其是牛客,寒假时没有怎么管,现在后悔了qaq),蓝桥杯也快来了,一下子事情多了起来,反而不知道要看什么了,在此先立个flag----蓝桥杯拿个奖(能省一最好,没有的话省2/3也不是不行)        

同时写一下近期计划:到4月前把寒假的题补完,到4月10号前刷完真题。

进入正题:

什么是0/1trie? 就是一个二叉树,左节点为0,右节点为1,因此,某一个数的二进制从高位到低位可以用0/1trie从根节点往下走写出。

下面让我们直接看题吧:

直接枚举的话复杂度为n^2,因此我们考虑用0/1trie,我们先枚举数,然后如果有不同的位就选它即可,下面是AC代码(可以当模板记):

#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int n,a[N];
int ch[N*31][2],idx;
void insert(int x){
	int p=0;
	for(int i=30;i>=0;i--){
		int j=(x>>i)&1;
		if(ch[p][j]==0) ch[p][j]=++idx;
		p=ch[p][j];
	}
}
int query(int x){
	int p=0,res=0;
	for(int i=30;i>=0;i--){
		int j=(x>>i)&1;
		if(ch[p][!j]){
			res+=(1<<i);
			p=ch[p][!j];
		}
		else p=ch[p][j];
	}
	return res;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		insert(a[i]);
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		ans=max(ans,query(a[i]));
	}
	cout<<ans;
}

来个比较难的(出自寒假训练营2)

首先,我们只要考虑最大值与最小值,于是我们sort一下,当我们把相应的i与j确定后,中间的数相当于都可以有选与不选,因此为2^(j-i-1)种,现在问题就转化成了如何求符合的max,min对,我们不妨先枚举max,我们同时构造0/1trie,我们知道:

1.如果k的一位为0,那么max^min为1的话他的子树都可以选。

2.若k的一位为1,那么max^min只能选1.

因此,我们让其走下去不断累加答案,至于一个串贡献的方案数,我们2^(j-i-1)=2^(j-1)/2^i,于是我们在树上用逆元维护1/2^i即可。

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10,mod=1e9+7;
long long son[10000100][2],w[10000100],idx;
long long n,k,a[N];
bool cmp(int a,int b){
    return a<b;
}
long long qpow(long long a,long long b){
    long long res=1;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
void insert(long long x,long long id){
    long long p=0,inv=qpow(qpow(2,id),mod-2);
    for(int i=30;i>=0;i--){
        int u=(x>>i)&1;
        if(son[p][u]==0) son[p][u]=++idx;
        p=son[p][u];
        w[p]=(w[p]+inv)%mod;
    }
}
long long quary(long long x){
    long long res=0,p=0;
    for(int i=30;i>=0;i--){
        int u=(x>>i&1)^(k>>i&1);
        if(k>>i&1) res=(res+w[son[p][1-u]])%mod;
        if(son[p][u]==0) return res;
        p=son[p][u];
    }
    return (res+w[p])%mod;
}
void solve(){
    cin>>n>>k;
    for(int i=0;i<=idx;i++){
        son[i][0]=0;
        son[i][1]=0;
        w[i]=0;
    }
    idx=0;
    for(int i=1;i<=n;i++) cin>>a[i];
    sort(a+1,a+n+1,cmp);
    long long ans=0;
    for(int i=1;i<=n;i++){
        ans=(ans+quary(a[i])*qpow(2,i-1)%mod+1)%mod;
        insert(a[i],i);
    }
    cout<<ans;
    return;
}
int main(){
    ios::sync_with_stdio(false),cin.tie(nullptr);
    int t;
    cin>>t;
    while(t--){
        solve();
        cout<<endl;
    }
}

相关推荐

  1. 备考01

    2024-03-20 11:26:02       26 阅读
  2. 备考随手记: practise01

    2024-03-20 11:26:02       18 阅读
  3. day01.

    2024-03-20 11:26:02       17 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-20 11:26:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-20 11:26:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-20 11:26:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-20 11:26:02       20 阅读

热门阅读

  1. 【数据库】MySQL表的增删改查(二)

    2024-03-20 11:26:02       21 阅读
  2. clickhouse使用心得

    2024-03-20 11:26:02       33 阅读
  3. Day23 二叉树09

    2024-03-20 11:26:02       19 阅读
  4. SQL的ON DUPLICATE KEY UPDATE使用方法

    2024-03-20 11:26:02       20 阅读
  5. 写了几个难一点的sql

    2024-03-20 11:26:02       18 阅读
  6. 部署dagu_1.12.10+replicadb0.15.1+sqlline1.12

    2024-03-20 11:26:02       19 阅读
  7. accessToken

    2024-03-20 11:26:02       16 阅读
  8. 理解C#和.NET的应用模型

    2024-03-20 11:26:02       22 阅读
  9. 拌合楼管理系统(七) 海康威视摄像头视频预览

    2024-03-20 11:26:02       19 阅读
  10. vue将中国标准时间转成年月日

    2024-03-20 11:26:02       16 阅读