zoukankan      html  css  js  c++  java
  • hdu 5269 ZYB loves Xor I(字典树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5269

    思路分析:当lowbit(AxorB)=2p 时,表示A与B的二进制表示的0-p-1位相等,第p位不同;考虑维护一棵字母树,将所有数字

    转换为二进制形式并且从第0位开始插入树中,并在每个节点中记录通过该结点的数字数目;最后统计答案,对于每一个数字,

    对于在其路径中的每一个结点X,假设其为第K层,统计通过与该结点不同的值的结点的数目count,则结果增加count*2k; 

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    const int MAX_N = 5 * 10000 + 100;
    int num[MAX_N];
    struct Node{
        Node *child[2];
        int count;
        Node(){
            count = 0;
            memset(child, 0, sizeof(child));
        }
        Node(int value){
            count = value;
            memset(child, 0, sizeof(child));
        }
    };
    
    void Insert(Node *head, int value){
        Node *pre = head, *next = NULL;
        for (int i = 0; i < 30; ++ i){
            if (pre->child[value & 1] == NULL){
                pre->child[value & 1] = new Node(1);
                pre = pre->child[value & 1];
            }else{
                next = pre->child[value & 1];
                next->count++;
                pre = next;
            }
            value >>= 1;
        }
    }
    
    void MakeEmpty(Node *node){
        node->count = 0;
        if (node->child[0])
            MakeEmpty(node->child[0]);
        if (node->child[1])
            MakeEmpty(node->child[1]);
    }
    
    long long Query(Node *head, int value){
        Node *pre = head, *next = NULL, *other;
        long long ret = 0;
    
        for (int i = 0; i < 30; ++ i){
            next = pre->child[value & 1];
            other = pre->child[(value & 1) ^ 1];
            if (other)
                ret = (ret + other->count * (1 << i)) % 998244353;
            pre = next;
            value >>= 1;
        }
        return ret;
    }
    
    int main(){
        int case_times, n;
        int case_id = 0;
    
        scanf("%d", &case_times);
        while (case_times--){
            Node *head = new Node();
    
            scanf("%d", &n);
            for (int i = 0; i < n; ++i){
                scanf("%d", &num[i]);
                Insert(head, num[i]);
            }
    
            long long ans = 0;
            for (int i = 0; i < n; ++i)
                ans = (ans + Query(head, num[i])) % 998244353;
            MakeEmpty(head);
            printf("Case #%d: %I64d
    ", ++case_id, ans);
        }
        return 0;
    }
  • 相关阅读:
    Scala(四)流程控制
    Scala(九)异常
    Idea中安装翻译插件
    hiveserver2启动卡住问题解决方案
    Scala(十)隐式转换
    Scala(七)集合
    Scala(六)面向对象
    Scala(八)模式匹配
    SharePoint 2010 文档库添加文件icon
    Windows Server 2008 r2 在Hyperv里搭建SharePoint 2010开发环境
  • 原文地址:https://www.cnblogs.com/tallisHe/p/4579756.html
Copyright © 2011-2022 走看看