zoukankan      html  css  js  c++  java
  • 字典树

     

    字典树是一颗无根树,可以是01字典树,也可以是字符串字典树。

    J - Coolbits

     ZOJ - 4135 

    给出n个区间,每个区间里拿出一个数,使得总体异或值最大,求最大异或值。

    一个一个枚举数是不行的,时间肯定不对,于是考虑枚举二进制位数。

    从高位到低位枚举的贪心是正确的,

    当你枚举一个区间当前位满足1的时候,就应该把区间放缩,掰成这个位为1的区间,

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e5+5;
    int n,c;
    ll R[N],L[N];
    bool check(ll x){
        c+=x;
        for(int i=1;i<=n;i++){
            ll a=L[i],b=R[i];
            if((a|x)!=a){
                a+=x;a&=c;
            }
            if((b|x)!=b){
                b-=x;b|=(x-1);
            }
            if(a>b)return 0;
        }
        return 1;
    }
    void work(ll x){
       for(int i=1;i<=n;i++){
            ll a=L[i],b=R[i];
            if((a|x)!=a){
                a+=x;a&=c;
            }
            if((b|x)!=b){
                b-=x;b|=(x-1);
            }
            L[i]=a;R[i]=b;
            // if(a>b)return 0;
        }
        
    }
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
        scanf("%d",&n);
        c=0;
        ll ans=0;
        for(int i=1;i<=n;i++)scanf("%lld %lld",&L[i],&R[i]);
        for(int i=30;i>=0;i--){
            if(check(1<<i)){
                ans+=(1<<i);
                work((1<<i));
            }
        }
        printf("%lld
    ",ans);
        }
        // system("pause");
        return 0;
    }
    View Code

     

    F - F

     HDU - 4825 

    01字典树,

    给出一个序列,

    每次询问x,求序列元素最大异或值,

    简单字典树,直接建树查询。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int inf=0x3f3f3f3f;
    const int N=1e5+5;
    int tot;
    ll val[N*32];
    ll trie[N*32][2];
    void insert(ll x){
        int u=0;
        for(int i=32;i>=0;i--){
            int id=(x>>i)&1;
            if(!trie[u][id])trie[u][id]=++tot;
            u=trie[u][id];
        }
        // val[u][id]=x;
        val[u]=x;
    }
    ll query(ll x){
        int u=0;
        for(int i=32;i>=0;i--){
            int id=(x>>i)&1;
            if(trie[u][id^1])u=trie[u][id^1];
            else u=trie[u][id];
        }
        return val[u];
    }
    int main(){
        int n,m,t,kase=0;
        scanf("%d",&t);
        while(t--){
            memset(trie,0,sizeof trie);
            tot=0;
            ll x;
            scanf("%d %d",&n,&m);
            for(int i=1;i<=n;i++){scanf("%lld",&x);insert(x);}
            printf("Case #%d:
    ",++kase);
            while(m--){
                scanf("%lld",&x);
                printf("%lld
    ",query(x));
            }
    
    
        }
        // system("pause");
        return 0;
    }
    // J题意:给你一个n,统计在树状数组找lowbit过程中,实际变化的量的数的和
    // I题意:给你一个数,问你他可以由几个回文数相加构成,他们是什么
    View Code
  • 相关阅读:
    Nginx配置文件详解
    Mycat概述
    日志切割之Logrotate
    js数组(二)
    js数组(一)
    sass颜色
    scss
    HTML5新属性
    HTML5新元素
    Bootstrap
  • 原文地址:https://www.cnblogs.com/littlerita/p/12709602.html
Copyright © 2011-2022 走看看