Kanade's trio
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 960 Accepted Submission(s): 361
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
Source
Recommend
题解:http://blog.csdn.net/dormousenone/article/details/76570172
这题:一直wa,把 tree[] 数组中的int改 long long 就错了,诶找了半天错误
#include <iostream> #include<cstring> #include<cstdio> using namespace std; struct node { int cnt,ext; int nxt[2]; }tree[500010*31]; int a[500000+10],num[30],cnt[31][2]; long long ans,ext; int T,n,tsize; void cal(int k,long long c) { ans+=(tree[k].cnt-1)*tree[k].cnt/2; ext+=tree[k].cnt*(c-tree[k].cnt)-tree[k].ext; } void solve() { int tmp=0; for(int i=0;i<=29;i++) { if (!tree[tmp].nxt[num[i]]) tree[tmp].nxt[num[i]]=++tsize; if (tree[tmp].nxt[1-num[i]]) cal(tree[tmp].nxt[1-num[i]],cnt[i][1-num[i]]); tmp=tree[tmp].nxt[num[i]]; tree[tmp].cnt++; tree[tmp].ext+=cnt[i][num[i]]-tree[tmp].cnt; } return; } int main() { scanf("%d",&T); for(;T>0;T--) { scanf("%d",&n); memset(cnt,0,sizeof(cnt)); memset(tree,0,tsize*16+16); tsize=0; ans=ext=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); int tmp=a[i]; for(int j=29;j>=0;j--) { cnt[j][tmp%2]++; num[j]=tmp%2; tmp/=2; } solve(); } printf("%lld\n",ans+ext); } return 0; }