2017多校训练Contest3: 1004 Kanade's sum hdu6059

来源:互联网 发布:sop8单片机实践应用 编辑:程序博客网 时间:2024/06/05 17:52

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.

1T20

1n5105

0A[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]
 

Output
For each test case , output an integer , which means the answer.
 

Sample Input
151 2 3 4 5
 

Sample Output
6


枚举j,字典树维护前缀后缀

#include<cstdio>#include<string>#include<cstring>#include<algorithm>#include<cmath>#include<cassert>using namespace std;bool bst;const int N=15100000;long long an;int n,m,s;long long w[40][2];int tre[N][2],v1[N],v2[N];int a[N];int tot;int r1=0,r2=0;bool bed;const int M=30;void change(int x,int t){    int p=0;    if (t)    {        for (int j=M;j>=0;j--)        {            int k=(x&(1<<j))>0;            v1[tre[p][k]]++;            w[j][k]+=v2[tre[p][1-k]];            p=tre[p][k];        }    }    else    {        for (int j=M;j>=0;j--)        {            int k=(x&(1<<j))>0;            v2[tre[p][k]]--;            w[j][1-k]-=v1[tre[p][1-k]];            p=tre[p][k];        }    }}void calc(int x){    for (int j=M;j>=0;j--)    {        int k=(x&(1<<j))>0;        an+=w[j][k];    }}int main(){    //freopen("a.in","r",stdin);    int T;    scanf("%d",&T);    while (T--)    {        scanf("%d",&n);        for (int i=1;i<=n;i++)        scanf("%d",&a[i]);        for (int i=0;i<=tot;i++) tre[i][0]=tre[i][1]=v1[i]=v2[i]=0;        memset(w,0,sizeof(w));        tot=0;        for (int i=1;i<=n;i++)        {            int p=0;            for (int j=M;j>=0;j--)            {                int k=(a[i]&(1<<j))>0;                if (!tre[p][k]) tre[p][k]=++tot;                p=tre[p][k];                v2[p]++;            }        }        an=0;        for (int i=1;i<=n;i++)        {            change(a[i],0);            calc(a[i]);            change(a[i],1);        }        printf("%lld\n",an);    }}