Codeforces 486 Div.3 CF988C Equal Sums

题意: 给出k个数列,要求选出任意两个数列i和j,使得第i个数列减去第n个数的和,等于第j个数列减去第m个数的和。求i、j、nn、m。

题目链接:http://codeforces.com/contest/988/problem/C

错误想法

统计所有数列的和(a[i].value表示第i个数列的和是多少),枚举两个数列(i、j),枚举第i个数列的每个数字n。那么我们就确定了四个所求数中的三个,对于第四个数m进行二分即可。 \[ a[i].value - n == a[j].value - m \]

1
2
3
4
5
6
for( 数列 i = 1 to k ) 
for( 数列 j = 1 to i )
for( 元素 n = 1 to a[i].size() )
二分查找a[j]中是否存在m( m == a[j].value - a[i],value + n )
找到了输出YES.
输出NO

算法复杂度: \(O(k^3*logn)\)

一开始考虑到这个肯定过不了,不过无意间看到保证所有数据元素加起来不超过\(2e5\)个,不知道怎么脑子抽了就写了。 但是实际上显然不能过的,只要每个数列一个数字,直接将近\(4e10\),TLE是肯定的。 写了以后疯狂Wrong Answer.... TLE我也就接受了。应该是正常的,然而疯狂WA是怎么一回事。 查了两三天的错,主要的问题是: - 二分没有排序! (这问题,orz) - 排序后,某下标错了……

和空气斗智斗勇
和空气斗智斗勇

感觉自己问题出在,想到了一个简单的不行的结论,就以为get到了这道题的trick,然后就非常兴奋的撞了上去越陷越深。

正确做法

1
2
3
map< 去掉一个数后的和 , 
pair<第一次出现这个和的时候的数列,第一次出现这个和的时候的数列元素位置 >
>

只要遍历每一个数字,当这个数字在map中没有出现过的时候,放入这样一个map中,当这个数字在map中出现了的时候,输出map中记录的第一次出现的位置和当前位置即可。 时间复杂度:\(O(k*logn)\)

总结

以后对于这种出现两次,要找一对的情况之类的,可以考虑先存一下第一次出现的时候的情况,然后第二次出现的时候直接输出。



本文标题:Codeforces 486 Div.3 CF988C Equal Sums

文章作者:Xie Keyi

发布时间:2018年06月06日 - 17:06

原始链接:https://xiekeyi98.com/5aa8be3b.html

许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 转载请保留原文链接及作者。