hdu 5269 ZYB loves Xor I

来源:互联网 发布:方舟生存进化淘宝价格 编辑:程序博客网 时间:2024/06/06 17:07

题目:

ZYB喜欢研究Xor,现在他得到了一个长度为n的数组A。于是他想知道:对于所有数对(i,j)(i[1,n],j[1,n])lowbit(AixorAj)之和为多少.由于答案可能过大,你需要输出答案对998244353取模后的值定义lowbit(x)=2k,其中k是最小的满足(x and 2k)>0的数特别地:lowbit(0)=0

输入:

一共T(T10)组数据,对于每组数据:第一行一个正整数n,表示数组长度第二行n个非负整数,第i个整数为Ain[1,5104]Ai[0,229]
输出:

每组数据输出一行Case #x: ans。x表示组数编号,从1开始。ans为所求值。

官方题解:

我们考虑,当A xor B的答案为2p时,AB表示成二进制数后末p1位肯定相同于是我们维护一颗字母树,将每个数表示成二进制数后翻转可以下,插入字母树统计答案时,我们找出Ai的二进制数翻转后在字母树上的路径,对于路径上每个点x,设他走的边是v,且当前为第k位,则和他xor后lowbit为2k的数的个数为trans(x,v^1)的子树大小。trans(x,v)表示字母树上在结点x,走连出去的字母为v的边到达的结点时间复杂度:O(nlogA)

分析:

刚开始用map瞎搞,TLE~,怎么都没想到用字典树啊,还是智商不够用。


以下附上代码:

#include <algorithm>#include <iostream>#include <sstream>#include <fstream>#include <cstring>#include <cstdio>#include <vector>#include <cctype>#include <cmath>#include <stack>#include <queue>#include <list>#include <map>#include <set>using namespace std;typedef long long ll;typedef unsigned long long ull;const int maxn = 50005;const int mod = 998244353;struct Node{  int cnt;  Node *l, *r;//0 1    ~Node(){  }};struct Tree{  Node *root;    Tree(){root = new Node;root->l = 0; root->r = 0;}    void insert(int v){    Node *p = root;    for(int i = 0; i < 30; i++){      if(v&(1<<i)){//1                if(p->r == 0){          Node *q = new Node;          q->cnt = 0;          q->l = 0;          q->r = 0;          p->r = q;        }        p = p->r;        p->cnt++;      }      else{//0        if(p->l == 0){          Node *q = new Node;          q->cnt = 0;          q->l = 0;          q->r = 0;          p->l = q;        }        p = p->l;        p->cnt++;              }    }          }    int find(int v){    Node *p = root;    int res = 0;    for(int i = 0; i < 30; i++){      if(v&(1<<i)){//1        if(p->l != 0){          res += (p->l->cnt)*(1<<i);          res %= mod;        }        p = p->r;      }      else{//0        if(p->r != 0){          res += (p->r->cnt)*(1<<i);          res %= mod;         }        p = p->l;      }    }    return res;  }    ~Tree(){    }  };int n;int a[maxn];int main(){  int t;  int ans;  scanf("%d",&t);  for(int k = 1; k <= t; k++){    Tree x;    scanf("%d",&n);    ans = 0;    for(int i = 0; i < n; i++){      scanf("%d",&a[i]);      x.insert(a[i]);    }    for(int i = 0; i < n; i++){      ans += x.find(a[i]);      ans %= mod;    }    printf("Case #%d: %d\n",k,ans);  }return 0;}


0 0
原创粉丝点击