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

    Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么?
    Input输入包含若干组测试数据,每组测试数据包含若干行。
    输入的第一行是一个整数T(T < 10),表示共有T组数据。
    每组数据的第一行输入两个正整数N,M(<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32。Output对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
    对于每个询问,输出一个正整数K,使得K与S异或值最大。Sample Input

    2
    3 2
    3 4 5
    1
    5
    4 1
    4 6 5 6
    3

    Sample Output

    Case #1:
    4
    3
    Case #2:
    4

    题目分析 : 给你一堆数,一些询问,问当前输入的数同上面的哪个数异或值最大
    思路分析 : 对于当前输入的 n ,我们很容易判断出其与哪个数异或的值最大,当然这个数不一定出现在上来的一堆数中,在这里字典树搞一下就很方便了
    不是很懂的地方就是字典树用数组写内存应该开多大的。
    代码示例 :
    #define ll long long
    const int maxn = 1e5+5;
    const double pi = acos(-1.0);
    const int inf = 0x3f3f3f3f;
    
    int pre[maxn][40];
    int arr[maxn];
    int len;
    int tree[maxn*100][2];
    int ans[50];
    
    void init(){
        ans[0] = 1;
        for(int i = 1; i <= 32; i++) ans[i] = ans[i-1]*2;
    }
    
    void fun(int x){
        queue<int>que;
        int f = arr[x];
        while(f){
            que.push(f%2);
            f /= 2;
        }
        int k = len;
        while(!que.empty()){
            pre[x][k--] = que.front();
            que.pop();
        }
    }
    
    int rt = 1;
    void build(int x){
        int u = 0, v;
        
        for(int i = 1; i <= len; i++){
            v = pre[x][i];
            if (!tree[u][v]) tree[u][v] = rt++;
            u = tree[u][v];        
        }
    }
    int pp[50];
    int an;
    void query(){
        int u = 0, v;
        an = 0;
        
        for(int i = 1; i <= len; i++){
            v = pp[i];
            //if (!tree[u][v]) {printf("*****
    "); v ^= 1; u = tree[u][v]; an += (v)*ans[len-i]; }
            //else {printf("&&&&&&&&&& 
    "); u = tree[u][v]; an += v*ans[len-i];}
            if (!tree[u][v]) v ^= 1;
            u = tree[u][v];
            an += v*ans[len-i];
            //printf("an = %d v = %d 
    ", an, v);
        }
    }
    
    int main() {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        int t, x;
        int kase = 1;
        
        cin >> t;
        init();
        while(t--){
            int n, m;
            cin >> n >> m;
            int ma = 0;
            for(int i = 1; i <= n; i++){
                scanf("%d", &arr[i]);            
                ma = max(ma, arr[i]);
            }
            len = floor(log(ma)/log(2))+1;
            //printf("len = %d
    ", len);
            memset(pre, 0, sizeof(pre));
            memset(tree, 0, sizeof(tree));
            rt = 1;
            for(int i = 1; i <= n; i++){
                fun(i);
                build(i);
                //printf("rt = %d
    ", rt);
            }
            //for(int i = 1; i <= n; i++){
                //for(int j = 1; j <= len; j++){
                    //printf("%d", pre[i][j]);
                //}
                //printf("
    ");
            //}
            printf("Case #%d:
    ", kase++);
            while(m--){
                scanf("%d", &x);
                memset(pp, 0, sizeof(pp));
                int lenth = floor(log(x)/log(2)) + 1;
                queue<int>que;
                int f = x;
                while(f) {
                    que.push(f%2);
                    f /= 2;
                }
                if (lenth >= len){
                    for(int i = len; i >= 1; i--){pp[i] = que.front(); que.pop();}    
                }
                else {
                    for(int i = len; i >= len-lenth+1; i--) {pp[i]=que.front(); que.pop();}
                }
                for(int i = 1; i <= len; i++) pp[i] ^= 1;
                //for(int i = 1; i <= len; i++) printf("%d ", pp[i]);
                //printf("
    ");
                query();      
                printf("%d
    ", an);
            } 
        }
        return 0;
    }
    

      

    东北日出西边雨 道是无情却有情
  • 相关阅读:
    easyui学习笔记3—在展开行内的增删改操作
    easyui学习笔记2—在行内进行表格的增删改操作
    4星|《贫穷的本质》:小额贷款对穷人帮助有限,助推政策也许是更好的
    科技类好书12本
    咨询公司等专业服务公司的权力结构:3星|《哈佛商业评论》第4期
    投资、投机、经济周期相关20本书,其中好书8本半
    3星|《进化:中国互联网生存法则》:点评十年来互联网公开大事
    黑洞有毛 or 黑洞无毛:4星|《环球科学》2019年03月号
    3星|《给产品经理讲技术》:APP开发技术介绍,没有技术背景的话恐怕只能看懂书中的比喻和结论
    2星|《为什么我们总是在逃避》:尝试用精神分析理论解释常见负面情绪
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/8576331.html
Copyright © 2011-2022 走看看