zoukankan      html  css  js  c++  java
  • [hdu5101]计数问题

    http://acm.hdu.edu.cn/showproblem.php?pid=5101

    题目大意:给n个集合,求从两个不同集合里面各取一个数使得它们的和大于给定数的方案数。

    ans=从所有数里面取两个数的方案数-从每个集合里面取两个数的方案数(这是关键)


    如果不转换也可以这么做,离散一下,然后树状数组统计也行,具体见代码。

    代码一:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <map>
     7 #include <vector>
     8 #include <stack>
     9 #include <string>
    10 #include <ctime>
    11 #include <queue>
    12 #define mem0(a) memset(a, 0, sizeof(a))
    13 #define mem(a, b) memset(a, b, sizeof(a))
    14 #define lson l, m, rt << 1
    15 #define rson m + 1, r, rt << 1 | 1
    16 #define eps 0.0000001
    17 #define lowbit(x) ((x) & -(x))
    18 #define memc(a, b) memcpy(a, b, sizeof(b))
    19 #define x_x(a) ((a) * (a))
    20 #define LL long long
    21 #define DB double
    22 #define pi 3.14159265359
    23 #define MD 10000007
    24 #define INF (int)1e9
    25 #define max(a, b) ((a) > (b)? (a) : (b))
    26 using namespace std;
    27 int b[110000];
    28 LL solve(int a[], int n, int x)
    29 {
    30         LL ans = 0;
    31         for(int i = 1; i <= n; i++) {
    32                 int tmp = upper_bound(a + 1, a + 1 + n, x - a[i]) - a;
    33                 ans += n - tmp + 1;
    34         }
    35         return ans;
    36 }
    37 int main()
    38 {
    39         //freopen("input.txt", "r", stdin);
    40         //freopen("output.txt", "w", stdout);
    41         int n, k, T;
    42         cin>> T;
    43         while(T--) {
    44                 cin>> n>> k;
    45                 LL ans1 = 0, ans2 = 0;
    46                 int tot = 0;
    47                 for(int i = 1; i <= n; i++) {
    48                         int m, a[110];
    49                         cin>> m;
    50                         for(int j = 1; j <= m; j++) {
    51                                 scanf("%d", &a[j]);
    52                                 b[++tot] = a[j];
    53                         }
    54                         sort(a + 1, a + 1 + m);
    55                         ans1 += solve(a, m, k);
    56                 }
    57                 sort(b + 1, b + 1 + tot);
    58                 ans2 = solve(b, tot, k);
    59                 cout<< (ans2 - ans1) / 2<< endl;
    60         }
    61         return 0;
    62 }
    View Code

    代码二(树状数组):

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <map>
      7 #include <vector>
      8 #include <stack>
      9 #include <string>
     10 #include <ctime>
     11 #include <queue>
     12 #define mem0(a) memset(a, 0, sizeof(a))
     13 #define mem(a, b) memset(a, b, sizeof(a))
     14 #define lson l, m, rt << 1
     15 #define rson m + 1, r, rt << 1 | 1
     16 #define eps 0.0000001
     17 #define lowbit(x) ((x) & -(x))
     18 #define memc(a, b) memcpy(a, b, sizeof(b))
     19 #define x_x(a) ((a) * (a))
     20 #define LL long long
     21 #define DB double
     22 #define pi 3.14159265359
     23 #define MD 10000007
     24 #define INF (int)1e9
     25 #define max(a, b) ((a) > (b)? (a) : (b))
     26 using namespace std;
     27 map<int, int> hash;
     28 int nn, tot, arr[220000], arr0[220000], c[220000], a[1200][120], m[1200];
     29 void init()
     30 {
     31         sort(arr + 1, arr + 1 + tot);
     32         arr0[1] = arr[1];
     33         nn = 1;
     34         hash[arr0[1]] = 1;
     35         for(int i = 2; i <= tot; i++) {
     36                 if(arr[i] != arr[i - 1]) {
     37                         arr0[++nn] = arr[i];
     38                         hash[arr[i]] = nn;
     39                 }
     40         }
     41 }
     42 void update(int p, int x)
     43 {
     44         while(p <= nn) {
     45                 c[p] += x;
     46                 p += lowbit(p);
     47         }
     48 }
     49 void insert(int a[], int n)
     50 {
     51         for(int i = 1; i <= n; i++) {
     52                 int tmp = hash[a[i]];
     53                 update(tmp, 1);
     54         }
     55 }
     56 int sum(int p)
     57 {
     58         int ans = 0;
     59         while(p) {
     60                 ans += c[p];
     61                 p -= lowbit(p);
     62         }
     63         return ans;
     64 }
     65 int query(int L, int R)
     66 {
     67         return sum(R) - sum(L - 1);
     68 }
     69 int find(int x)
     70 {
     71         int l = 1, r = nn;
     72         while(l < r) {
     73                 int m = (l + r) >> 1;
     74                 if(arr0[m] > x) r = m;
     75                 else l = m + 1;
     76         }
     77         return l;
     78 }
     79 int main()
     80 {
     81         //freopen("input.txt", "r", stdin);
     82         //freopen("output.txt", "w", stdout);
     83         int T;
     84         cin>> T;
     85         while(T--) {
     86                 hash.clear();
     87                 mem0(c);
     88                 int n, k;
     89                 cin>> n>> k;
     90                 tot = 0;
     91                 for(int i = 1; i <= n; i++) {
     92                         cin>> m[i];
     93                         for(int j = 1; j <= m[i]; j++) {
     94                                 scanf("%d", &a[i][j]);
     95                                 arr[++tot] = a[i][j];
     96                         }
     97                 }
     98                 init();
     99                 insert(a[1], m[1]);
    100                 LL ans = 0;
    101                 for(int i = 2; i <= n; i++) {
    102                         for(int j = 1; j <= m[i]; j++) {
    103                                 int tmp = find(k - a[i][j]);
    104                                 ans += query(tmp, nn);
    105                         }
    106                         insert(a[i], m[i]);
    107                 }
    108                 cout<< ans<< endl;
    109         }
    110         return 0;
    111 }
    View Code
  • 相关阅读:
    递归
    简单装饰器
    带函数参数的装饰器(复杂装饰器)的例子
    (转)MySQL 线程池内幕
    (转)http://blog.csdn.net/renfufei/article/details/38474435
    (转)RabbitMQ 中文文档
    (转) rabbitmq应用场景
    (转) Rabbitmq学习笔记
    (转)更换镜像rootvg卷组中的硬盘
    (转)AIX下镜像制作与取消,更换硬盘问题
  • 原文地址:https://www.cnblogs.com/jklongint/p/4095157.html
Copyright © 2011-2022 走看看