牛客网-小马哥的超级盐水 【折半查找】

链接:https://www.nowcoder.com/acm/contest/94/K
来源:牛客网

时间限制:C/C++ 5秒,其他语言10秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld

题目描述

小马哥有杯盐水,第杯有单位的盐和单位的水。小马哥很无聊,于是他想知道有多少种这杯盐水的非空子集,倒在一起之后盐和水的比是

输入描述:

输入第一行包含一个整数,代表数据组数。
每组数据第一行包含三个整数表示的最大公约数。
接下来行,第行包含两个整数

输出描述:

每组数据输出一行,包含一个整数表示非空子集的个数。
示例1

输入

1
5 1 2
1 2
1 2
1 2
1 2
1 4

输出

15

n <= 35 如果直接枚举状态肯定超时,但如果枚举 n/2的状态就不会超时,所以可以把n分成两份,分别枚举状态,根据第一份的状态,二分搜索第二份的状态即可。
状态公式:(ai + aj) / ( bi + bj) = x / y
   => y * (ai + aj) = x * (bi + bj)
   => ai * y - bi * x = bj * x - aj * y

记录每个状态的 b和 * x - a和 * y就能得出答案。

附ac代码:
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <vector>
 6 #include <cmath>
 7 #include <string>
 8 using namespace std;
 9 typedef long long ll;
10 const int maxn = 400000;
11 ll a[maxn], b[maxn];
12 ll ansa[maxn], ansb[maxn];
13 int t;
14 int n;
15 ll  x, y;
16 int lea = 0;
17 void dfsa(int now, ll sum) {
18     if(now == n / 2) {
19         ansa[lea++] = sum;
20         return;
21     }
22     dfsa(now + 1, sum);
23     dfsa(now + 1, sum + (x * b[now] - y * a[now]));
24     
25     return;
26 }
27 int leb = 0;
28 void dfsb(int now,  int sum) {
29     if(now == n) {
30         ansb[leb++] = sum;
31         return;
32     }
33     dfsb(now + 1, sum);
34     dfsb(now + 1, sum + (x * b[now] - y * a[now]));
35     
36     return;
37 }
38 int main() {
39 
40     scanf("%d", &t);
41     while(t--) {
42         lea = 0;
43         leb = 0;
44         scanf("%d %lld %lld", &n, &x, &y);
45         for(int i = 0; i < n; ++i) {
46             scanf("%lld %lld", &a[i], &b[i]);
47         } 
48         dfsa(0, ll(0));
49         dfsb(n / 2, ll(0));
50     //    printf("%d %d
", lea, leb);
51         ll cnt = 0;
52         sort(ansb, ansb + leb);
53         for (int i = 0; i < lea; i++)
54             cnt += (upper_bound(ansb, ansb + leb, -ansa[i]) - ansb) - (lower_bound(ansb, ansb + leb, -ansa[i]) - ansb);
55         
56         printf("%lld
", cnt - 1);
57     }
58     return 0;
59 } 
View Code



原文地址:https://www.cnblogs.com/zmin/p/8848715.html