@hdu - 6687@ Rikka with Stable Marriage
@description@
给定一个稳定婚姻匹配问题,其中第 i 个男生与第 j 个女生之间的喜爱度为 ai xor bj。
现在需要你求出所有稳定婚姻匹配中 ∑(ai xor bj) 的最大值。
注:关于什么是稳定婚姻匹配。
第 i 个男生对于第 j 个女生有一个喜爱度 Aij,第 j 个女生对第 i 个男生有一个喜爱度 Bij(在本题中 Aij = Bij)。
一个稳定婚姻匹配应该满足:如果将 x 与 y 匹配,u 与 v 匹配,则不应该出现 x 对 v 的喜爱度 > x 对当前的 y 的喜爱度,且 v 对 x 的喜爱度 > v 对当前的 u 的喜爱度。
Input
第一行一个整数 T 表示数据组数。
对于每组数据,开头一行包含一个整数 n (1≤n≤10^5)。
第二行包含 n 个整数 a1, a2, ..., an (1≤ai≤10^9)。
第三行包含 n 个整数 b1, b2, ..., bn (1≤bi≤10^9)。
保证所有的 ai 互不相等,保证所有的 bi 互不相等。
Output
对于每组数据,输出一个整数表示 ∑(ai xor bj) 的最大值。如果无解输出 -1。
Sample Input
2
4
1 2 3 4
1 2 3 4
5
10 20 30 40 50
15 25 35 45 55
Sample Output
20
289
@solution@
稳定婚姻问题挺有意思的 www(虽然这道题基本只需要用到它的定义)。
稳定婚姻匹配不可能无解,所以无解输出 -1 是假的。
假如 x 在 y 心中是最棒的,y 在 x 心中是最棒的,则 x 与 y 一定可以存在于稳定婚姻匹配中。
且由于 ai, bi 互不相同,ax xor by 与其他的 ax xor bv, au xor ay 也一定不相同,且一定比它们大。
由此,如果 x, y 与其他人 u, v 匹配,一定会出现不稳定的情况。则可以发现 x 与 y 存在于所有稳定婚姻匹配中。
我们不断地找这样一对 (x, y),并把它们同时删去。
怎么找呢?假如 x 与 y 的喜爱度 ax xor by 是全局最大的,则他们一定是互相认为最棒的。
我们就不断地找 ax xor by 最大值及其对应的 x 与 y,然后删去 x 与 y 递归求解。
可以发现一定有一个时刻所有人都删完了,而且中途不会出现多种选择。故这个题中稳定婚姻匹配是唯一的。
那么问题就在于怎么不断地找 ax xor by 的最大值。
两个值的 xor 最大值可以联想到 trie 树。两棵 trie 树找结点 xor 最大值,或许我们可以进行 trie 的 “合并”。
对于两棵 trie 树 T1, T2,首先最高位尽量不同才能 xor 出来最大。
所以首先应该尝试递归 T1->child[0] 与 T2->child[1],T1->child[1] 与 T2->child[0] 看能否找到最大值。
如果有一棵树为空了,则匹配无法继续,直接停止递归并返回就好了。
此时注意到这两次递归并不会互相影响,且这两次递归找出来的一定比 0, 0 匹配、1, 1 匹配大,所以可以同时进行。
用不着像我们一开始的算法那样先找全局 xor 最大值,再找全局次大值……
过后还要尝试递归 T1->child[0] 与 T2->child[0],T1->child[1] 与 T2->child[1],将匹配剩余的继续拿去匹配。
复杂度?因为只有两棵树同时不为空时才会继续,那么复杂度 <= 将 n 对匹配插入 trie 树中的总复杂度。
即复杂度为 O(nlogA),A 为值域。
@accepted code@
#include <cstdio>
typedef long long ll;
const int MAXN = 100000;
int ch[2][2][35*MAXN + 5], cnt[2][35*MAXN + 5], ncnt[2];
int newnode(int t) {
int p = (++ncnt[t]);
ch[t][0][p] = ch[t][1][p] = cnt[t][p] = 0;
return p;
}
void insert(int rt, int dep, const int &x, const int &t) {
cnt[t][rt]++;
if( dep == -1 ) return ;
int dir = (x >> dep) & 1;
if( !ch[t][dir][rt] )
ch[t][dir][rt] = newnode(t);
insert(ch[t][dir][rt], dep - 1, x, t);
}
ll ans; int n;
void cal(int rt1, int rt2, int dep, int x) {
if( !cnt[0][rt1] || !cnt[1][rt2] )
return ;
if( dep == -1 ) {
ans += x, cnt[0][rt1]--, cnt[1][rt2]--;
return ;
}
cal(ch[0][0][rt1], ch[1][1][rt2], dep - 1, x|(1<<dep));
cal(ch[0][1][rt1], ch[1][0][rt2], dep - 1, x|(1<<dep));
cal(ch[0][0][rt1], ch[1][0][rt2], dep - 1, x);
cal(ch[0][1][rt1], ch[1][1][rt2], dep - 1, x);
cnt[0][rt1] = cnt[0][ch[0][0][rt1]] + cnt[0][ch[0][1][rt1]];
cnt[1][rt2] = cnt[1][ch[1][0][rt2]] + cnt[1][ch[1][1][rt2]];
}
void solve() {
scanf("%d", &n);
ncnt[0] = 0, newnode(0);
for(int i=1;i<=n;i++) {
int x; scanf("%d", &x);
insert(1, 30, x, 0);
}
ncnt[1] = 0, newnode(1);
for(int i=1;i<=n;i++) {
int x; scanf("%d", &x);
insert(1, 30, x, 1);
}
ans = 0; cal(1, 1, 30, 0);
printf("%lld\n", ans);
}
int main() {
int T; scanf("%d", &T);
while( T-- ) solve();
}
@details@
话说这种新的两棵 trie 树搞合并方法。。。感觉还是比较新颖的?
感觉以前都没有见过,又感觉好像很经典。。。
@hdu - 6687@ Rikka with Stable Marriage的更多相关文章
- 【HDOJ6687】Rikka with Stable Marriage(Trie树,贪心)
题意:给定两个长均为n的序列a和b,要求两两配对,a[i]和b[j]配对的值为a[i]^b[j],求配对后的值之和的最大值 n<=1e5,a[i],b[i]<=1e9 思路:和字典序最大的 ...
- 【HDU6687】Rikka with Stable Marriage(Trie树 贪心)
题目链接 大意 给定\(A,B\)两个数组,让他们进行匹配. 我们称\(A_i\)与\(B_j\)的匹配是稳定的,当且仅当目前所剩元素不存在\(A_x\)或\(B_y\)使得 \(A_i\oplus ...
- The Stable Marriage Problem
经典稳定婚姻问题 “稳定婚姻问题(The Stable Marriage Problem)”大致说的就是100个GG和100个MM按照自己的喜欢程度给所有异性打分排序.每个帅哥都凭自己好恶给每个MM打 ...
- HDU 5831 Rikka with Parenthesis II(六花与括号II)
31 Rikka with Parenthesis II (六花与括号II) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536 ...
- HDOJ 1914 The Stable Marriage Problem
rt 稳定婚姻匹配问题 The Stable Marriage Problem Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 6553 ...
- 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence
// 判断相同区间(lazy) 多校8 HDU 5828 Rikka with Sequence // 题意:三种操作,1增加值,2开根,3求和 // 思路:这题与HDU 4027 和HDU 5634 ...
- 【POJ 3487】 The Stable Marriage Problem (稳定婚姻问题)
The Stable Marriage Problem Description The stable marriage problem consists of matching members o ...
- [POJ 3487]The Stable Marriage Problem
Description The stable marriage problem consists of matching members of two different sets according ...
- POJ 3487 The Stable Marriage Problem(稳定婚姻问题 模版题)
Description The stable marriage problem consists of matching members of two different sets according ...
随机推荐
- chown权限命令
chown 命令用途更改与文件关联的所有者或组. 语法chown[ -f ] [ -h] [ -R ] Owner [ :Group ] { File ... | Directory ... } ...
- umask权限使用
很显然,系统中各种文件的权限设置对特定用户的数据安全有很大影响.但是要求用户逐一明确设置系统中每个文件的权限也是不现实的,为此,需要使用umask命令,该命令可以为用户账号中新文件的创建进行缺省设置. ...
- vue 权限管理
核心想法: 登陆后获得用户角色,通过角色获得用户的权限,注入权限对应的路由.刷新页面,从localStorage用角色(更好的方式是通过token)再次获得所属权限,再次注入路由.在管理界面左端循环权 ...
- 有趣的纯CSS实现动态晴阴雨雪
我们先来看看实现的效果吧 非常的美腻,对吧.这个是纯css,且单标签实现的哦~ 先贴完整代码,我们再来看看这个里面究竟有什么可以借鉴的知识点 <!DOCTYPE html> <htm ...
- Jdbc封装和对CURD的封装
1.查询emp表中的所有记录为例 2.测试类 public Emp getByNameAndEmail(String name, String email){ String sql = "s ...
- centos安装消息队列beanstalkd
起因:开始想在windows安装beanstalkd,可以找了很多资料都没有成功.最终还是妥协.在虚拟机上装一个centos系统,然后在centos上安装beanstalkd供windows使用 yu ...
- USACO 2.1.4
/* ID: weitong4 LANG: C++ TASK: holstein */ #include<stdio.h> #include<string.h> #define ...
- LintCode_453 将二叉树拆成链表
题目 将一棵二叉树按照前序遍历拆解成为一个假链表.所谓的假链表是说,用二叉树的 right 指针,来表示链表中的 next 指针. 样例 1 \ 1 2 / \ \ 2 5 => 3 / \ \ ...
- Java过滤器—Filter用法简介
一.什么是Filter? Filter译为过滤器. 由于年,Sun公司在Servlet2.3规范中添加了Filter功能,并在Servlet2.4中对Filter进行了细节上的补充. 二.运行原理: ...
- hibernate hql语句 group by having 的坑
我期望获得这个列表 然而,使用hql只能获得第一条数据,后来我琢磨了一下,和group by有关系 应该改成 成功查询到