Kanade's trio
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 926 Accepted Submission(s): 337
Problem Description
Give you an array
A[1..n]
,you need to calculate how many tuples
(i,j,k)
satisfy that
(i<j<k)
and
((A[i] xor A[j])<(A[j] xor A[k]))
There are T test cases.
1≤T≤20
1≤∑n≤5∗105
0≤A[i]<230
There are T test cases.
1≤T≤20
1≤∑n≤5∗105
0≤A[i]<230
Input
There is only one integer T on first line.
For each test case , the first line consists of one integer n ,and the second line consists of n integers which means the array A[1..n]
For each test case , the first line consists of one integer n ,and the second line consists of n integers which means the array A[1..n]
Output
For each test case , output an integer , which means the answer.
Sample Input
1 5 1 2 3 4 5
Sample Output
6
http://blog.csdn.net/HackerTom/article/details/76652749
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <queue>
#include <bitset>
using namespace std;
typedef long long LL;
const int N = 500000;
struct node
{
int child[2];
int small, cnt;
}trie[N*30+7];
int num[30][3];
LL ans;
int now[30];
int sz;
void update(int p,int pre)
{
ans+=(LL)trie[p].cnt*(trie[p].cnt-1)/2;
ans+=(LL)trie[p].cnt*(pre-trie[p].cnt)-trie[p].small;
return ;
}
void insert1()
{
for(int i=29,p=0;i>=0;i--)
{
int d=now[i];
if(!trie[p].child[d])trie[p].child[d]=sz++;
if(trie[p].child[1-d]) update(trie[p].child[1-d],num[i][1-d]);
p=trie[p].child[d];
trie[p].cnt++;
trie[p].small+=num[i][d]-trie[p].cnt;
}
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n, x;
memset(num,0,sizeof(num));
memset(trie,0,sizeof(trie));
sz=1,ans=0;
scanf("%d", &n);
while(n--)
{
scanf("%d", &x);
for(int i=0;i<30;i++,x>>=1)
{
int d=x&1;
num[i][d]++,now[i]=d;
}
insert1();
}
printf("%I64d\n",ans);
}
return 0;
}