zoukankan      html  css  js  c++  java
  • hdu5269 ZYB loves Xor I 异或,字典树

    hdu5269  ZYB loves Xor I   异或,字典树

    ZYB loves Xor I

     
     Accepts: 142
     
     Submissions: 696
     Time Limit: 2000/1000 MS (Java/Others)
     
     Memory Limit: 65536/65536 K (Java/Others)
    问题描述
    ZYB喜欢研究Xor,现在他得到了一个长度为nn的数组A。于是他想知道:对于所有数对(i,j)(i in [1,n],j in [1,n])(i,j)(i[1,n],j[1,n]),lowbit(A_i xor A_j)lowbit(Ai​​xorAj​​)之和为多少.由于答案可能过大,你需要输出答案对998244353取模后的值
    定义lowbit(x)=2^k2k​​,其中k是最小的满足(xx andand 2^k)>02k​​)>0的数
    特别地:lowbit(0)=0
    输入描述
    一共TT(T leq 10T10)组数据,对于每组数据:
    第一行一个正整数nn,表示数组长度
    第二行nn个非负整数,第ii个整数为A_{i}Ai​​
    n in [1,5*10^4]n[1,5104​​],A_i in [0,2^{29}]Ai​​[0,229​​]
    输出描述
    每组数据输出一行Case #x: ans。x表示组数编号,从1开始。ans为所求值。
    输入样例
    2
    5
    4 0 2 7 0
    5
    2 6 5 4 0
    输出样例
    Case #1: 36
    Case #2: 40

    之前一直没能过这题,现在看来就很简单了,以后看到异或也自然而然地想到字典树。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=(1<<29);
    const ll MOD=998244353;
    
    struct Trie
    {
        int ch[2];
        int siz;
    };Trie tr[maxn];int p;int rt;
    int n,a[maxn];
    
    int newnode()
    {
        tr[++p].siz=0;
        tr[p].ch[0]=tr[p].ch[1]=-1;
        return p;
    }
    
    void Init()
    {
        p=-1;
        rt=newnode();
    }
    
    void Insert(int t)
    {
        int k=rt;
        int c=0;
        tr[k].siz++;
        REP(i,0,30){
            if(t&(1<<i)) c=1;
            else c=0;
            if(tr[k].ch[c]==-1) tr[k].ch[c]=newnode();
            k=tr[k].ch[c];
            tr[k].siz++;
        }
    }
    
    ll query(int t)
    {
        int k=rt;
        int c;
        ll res=0;
        REP(i,0,30){
            if(t&(1<<i)) c=1;
            else c=0;
            if(~tr[k].ch[c^1]) res+=tr[tr[k].ch[c^1]].siz*(1<<i)%MOD;
            if(tr[k].ch[c]==-1) break;
            k=tr[k].ch[c];
        }
        return res%MOD;
    }
    
    int main()
    {
        freopen("in.txt","r",stdin);
        int casen=1;
        int T;cin>>T;
        while(T--){
            scanf("%d",&n);
            Init();
            REP(i,1,n){
                scanf("%d",&a[i]);
                Insert(a[i]);
            }
            ll ans=0;
            REP(i,1,n) ans+=query(a[i]),ans%=MOD;
            printf("Case #%d: %I64d
    ",casen++,ans);
        }
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    支持向量机 (三): 优化方法与支持向量回归
    支持向量机 (二): 软间隔 svm 与 核函数
    支持向量机 (一): 线性可分类 svm
    拉格朗日乘子法
    特征选择: 卡方检验、F 检验和互信息
    Python 多进程、多线程效率比较
    Umi+Dva搭建Cesium 3D开发环境
    React 项目生产版本迭代页面不刷新问题
    React-Native学习手册----搭建基于ios平台的开发环境
    Cesium 绘制点、线、面和测距
  • 原文地址:https://www.cnblogs.com/--560/p/4937748.html
Copyright © 2011-2022 走看看