@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 ...
随机推荐
- spring源码学习之bean的加载(三)
接着二中的继续写,那个都超过1000行了,哈,需要重新写一个,要不太长了,我都看不下去了 7.4 初始化bean doCreateBean函数中有这样一行代码:这行代码中initializeBean函 ...
- Django项目:CRM(客户关系管理系统)--49--40PerfectCRM实现全局账号注册+验证码+页面刷新保留信息
# gbacc_urls.py # ————————38PerfectCRM实现全局账号登录注销———————— from django.conf.urls import url from gbacc ...
- textarea标签中多出的空格
//这么写才能被正确渲染 <textarea></textarea> //这样就会有空格 <textarea> </textarea> 不能换行,涨姿势
- webpack4配置react开发环境
webpack4大大提高了开发效率,简化了配置复杂度,作为一个大的版本更新,作为一个对开发效率执着的爱折腾的程序员,已经忍不住要尝尝鲜了 首先是cli和webpack的分离,开发webpack应用程序 ...
- hdu 1059 Dividing(多重背包优化)
Dividing Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- NOIP2017到都不签签记
day 0: 校内开运动会,但是还是在机房学习了一天. 感觉上并没有多大用处,主要只是活跃一下思维而已. 然后就晚上上车出发去酒店. 下了个游戏王. 晚上叫了波宅急送,然后硬是腐了一个晚上. day ...
- 常见的HTML标签的嵌套规则
众所周知,HTML标签有两类: 块级元素div.h1~h6.address.blockquote.center.dir.dl.dt.dd.fieldset.form.hr.isindex.menu.n ...
- JAVA短信验证码 工具类
MsgCodeUtil.java package com.hg.util; import com.soyea.enums.ResultEnum; import com.soyea.exception. ...
- Leetcode22.Generate Parentheses括号生成
给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合. 例如,给出 n = 3,生成结果为: [ "((()))", "(()())& ...
- 关于Vector CANoe的讨论
默认排序 踩猫尾巴 汽车电子攻城狮 27 人赞同了该回答 好像是很久以前的问题啊,为什么会现在收到邀请. 我觉得 @lijuqqkiko 介绍的足够啦. 我再额外发散一点吧. 目前在CAN总线测试和 ...