码迷,mamicode.com
首页 > 其他好文 > 详细

bestcoders

时间:2015-07-14 22:42:10      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:acm   best   

ZYB loves Xor I

 
 Accepts: 142
 
 Submissions: 696
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
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个整数为Ai
n[1,5?104]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 <algorithm>
#include <cstring>
#include <cstdio>

using namespace std;

const long long MOD = 998244353;
const int maxn = 30;
const int M = 2;
long long  ans;

struct Node
{
    int v;
    Node *next[M];
};

struct Tree
{
    Node *root;
    int v;

    Tree()//constructor
    {
        root = new Node;
        root->v = 0;
        for(int i=0; i<M; i++)
            root->next[i] = NULL;
    }

    void insert(int t)
    {
        Node *p = root, *q;

        for(int i=0; i<maxn; i++)
        {
            int tmp = t&(1<<i);
            if(tmp) tmp = 1;
            if(p->next[tmp] == NULL)
            {
                q = new Node;
                q->v = 1;
                for(int i=0; i<M; i++)
                    q->next[i] = NULL;
                p->next[tmp] = q;
                p = q;
            }
            else
            {
                p = p->next[tmp];
                p->v++;
            }
        }
    }

    void find(int t)
    {
        Node *p = root;
        for(int i=0; i<maxn; i++)
        {
            long long tmp = t&(1<<i);
            if(tmp) tmp = 1;
            if(p->next[tmp^1] != NULL)
                ans = (ans + (p->next[tmp^1]->v)*(long long)(1<<i)) % MOD;
            p = p->next[tmp];
        }
    }
};

const int N = 50005;
int a[N];
int kase = 0;

int main()
{
    int T, n;
    scanf("%d", &T);
    while(T--)
    {
        ans = 0;
        Tree tree;
        scanf("%d", &n);
        for(int i=0; i<n; i++)
            {
                scanf("%d", &a[i]);
                tree.insert(a[i]);
            }
        for(int i=0; i<n; i++)
            tree.find(a[i]);
        printf("Case #%d: %I64d\n", ++kase, ans);
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

bestcoders

标签:acm   best   

原文地址:http://blog.csdn.net/dojintian/article/details/46883235

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!