HDU 6059 17多校3 Kanade's trio(字典树)

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

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

1

5

1 2 3 4 5

Sample Output

6

启发博客:http://blog.csdn.net/dormousenone/article/details/76570172

摘:

利用字典树维护前 k-1 个数。当前处理第 k 个数。

显然对于 k 与 i 的最高不相同位 kp 与 ip :

当 ip=0 , kp=1 时,该最高不相同位之前的 ihigher=khigher 。则 jhigher 可以为任意数,均不对 i, k 更高位(指最高不相同位之前的高位,后同)的比较产生影响。而此时 jp 位必须为 0 才可保证不等式 (Ai⊕Aj)<(Aj⊕Ak) 成立。

当 ip=1,kp=0 时,jp 位必须为 1 ,更高位任意。

故利用数组 cnt[31][2] 统计每一位为 0 ,为 1 的有多少个(在前 K-1 个数中)。在字典树插入第 k 个数时,同时统计最高不相同位,即对于每次插入的 p 位为 num[p] (取值 0 或 1),在同父节点对应的 1-num[p] 为根子树的所有节点均可作为 i 来寻找 j 以获取对答案的贡献。其中又仅要求 jp 与 ip (ip 值即 1-num[p]) 相同,故 jp 有 cnt[p][ 1-num[p] ] 种取值方案。

但是,同时需要注意 i 与 j 有在 A 数组的先后关系 (i<j) 需要保证。故在字典树中额外维护一个 Ext 点,记录将每次新加入的点与多少原有点可构成 i, j 关系。在后续计算贡献时去掉。

其余详见代码注释。

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<queue>
 5 #include<map>
 6 #include<vector>
 7 #include<cmath>
 8 #include<cstring>
 9 using namespace std;
10 long long ans1,ans2;
11 int num[35];//每一个数字的二进制转化
12 int cnt[35][2];//cnt[i][j]记录全部插入数字第i位为0、1分别的数字
13
14 struct trie
15 {
16     trie* next[2];
17     int cnt,ext;
18     trie()
19     {
20         next[0]=NULL;
21         next[1]=NULL;
22         cnt=0;//拥有当前前缀的数字个数
23         ext=0;//
24     }
25 };
26
27 void calc(trie* tmp,long long c)
28 {
29     ans1+=tmp->cnt*(tmp->cnt-1)/2;
30     ans2+=(c-tmp->cnt)*tmp->cnt-tmp->ext;
31 }
32
33 void insert(trie* r)
34 {
35     int i;
36     for(i=1;i<=30;i++)
37     {
38         if(r->next[num[i]]==NULL)
39             r->next[num[i]]= new trie;
40         if(r->next[1-num[i]]!=NULL)
41             calc(r->next[1-num[i]],cnt[i][1-num[i]]);
42         r=r->next[num[i]];
43         r->cnt++;
44         r->ext+=cnt[i][num[i]]-r->cnt;
45         //每个点存下同位同数不同父亲节点的数字个数且序号比本身小的
46     }
47     return ;
48 }
49
50 int main()
51 {
52     int T,n,tmp;
53     scanf("%d",&T);
54     while(T--)
55     {
56         scanf("%d",&n);
57         trie root;
58         ans1=0;//i,j选自同父亲节点
59         ans2=0;//i选自同父亲节点,j选择同位不同数不同父亲节点
60         memset(cnt,0,sizeof(cnt));
61         while(n--)
62         {
63             scanf("%d",&tmp);
64             for(int i=30;i>=1;i--)//这样可以保证不同大小的数字前缀都为0
65             {
66                 num[i]=tmp%2;
67                 cnt[i][num[i]]++;
68                 tmp/=2;
69             }
70             insert(&root);
71         }
72         printf("%lld\n",ans1+ans2);
73     }
74     return 0;
75 }

HDU 6059 17多校3 Kanade's trio(字典树)

时间: 2024-10-13 13:18:52

HDU 6059 17多校3 Kanade's trio(字典树)的相关文章

hdu6059 Kanade&#39;s trio 字典树+容斥

转自:http://blog.csdn.net/dormousenone/article/details/76570172 /** 题目:hdu6059 Kanade's trio 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6059 题意:含 N 个数字的 A 数组,求有多少个三元组 (i,j,k) 满足 i<j<k 且 (Ai⊕Aj)<(Aj⊕Ak) 思路: 利用字典树维护前 k-1 个数.当前处理第 k 个数. 显然对于 k 与 i 的

HDU 6060 17多校3 RXD and dividing(树+dfs)

Problem Description RXD has a tree T, with the size of n. Each edge has a cost.Define f(S) as the the cost of the minimal Steiner Tree of the set S on tree T. he wants to divide 2,3,4,5,6,…n into k parts S1,S2,S3,…Sk,where ?Si={2,3,…,n} and for all d

HDU 6045 17多校2 Is Derek lying?

题目传送:http://acm.hdu.edu.cn/showproblem.php?pid=6045 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 687    Accepted Submission(s): 389 Problem Description Derek and Alfia are good friends.Derek 

HDU 6077 17多校4 Time To Get Up 水题

Problem Description Little Q's clock is alarming! It's time to get up now! However, after reading the time on the clock, Little Q lies down and starts sleeping again. Well, he has 5 alarms, and it's just the first one, he can continue sleeping for a

HDU 6090 17多校5 Rikka with Graph(思维简单题)

Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them: For an undirected graph G with n nodes and m edges, we can define the distance between 

HDU 6055 17多校 Regular polygon(计算几何)

Problem Description On a two-dimensional plane, give you n integer points. Your task is to figure out how many different regular polygon these points can make. Input The input file consists of several test cases. Each case the first line is a numbers

HDU 6047 17多校 Maximum Sequence(优先队列)

Problem Description Steph is extremely obsessed with "sequence problems" that are usually seen on magazines: Given the sequence 11, 23, 30, 35, what is the next number? Steph always finds them too easy for such a genius like himself until one da

HDU 6050 17多校2 Funny Function(数学+乘法逆元)

Problem Description Function Fx,ysatisfies:For given integers N and M,calculate Fm,1 modulo 1e9+7. Input There is one integer T in the first line.The next T lines,each line includes two integers N and M .1<=T<=10000,1<=N,M<2^63. Output For eac

HDU 6092 17多校5 Rikka with Subset(dp+思维)

Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them: Yuta has n positive A1−An and their sum is m. Then for each subset S of A, Yuta calcula