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

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

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


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

代码一:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#include <stack>
#include <string>
#include <ctime>
#include <queue>
#define mem0(a) memset(a, 0, sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define eps 0.0000001
#define lowbit(x) ((x) & -(x))
#define memc(a, b) memcpy(a, b, sizeof(b))
#define x_x(a) ((a) * (a))
#define LL long long
#define DB double
#define pi 3.14159265359
#define MD 10000007
#define INF (int)1e9
#define max(a, b) ((a) > (b)? (a) : (b))
using namespace std;
int b[];
LL solve(int a[], int n, int x)
{
LL ans = ;
for(int i = ; i <= n; i++) {
int tmp = upper_bound(a + , a + + n, x - a[i]) - a;
ans += n - tmp + ;
}
return ans;
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
int n, k, T;
cin>> T;
while(T--) {
cin>> n>> k;
LL ans1 = , ans2 = ;
int tot = ;
for(int i = ; i <= n; i++) {
int m, a[];
cin>> m;
for(int j = ; j <= m; j++) {
scanf("%d", &a[j]);
b[++tot] = a[j];
}
sort(a + , a + + m);
ans1 += solve(a, m, k);
}
sort(b + , b + + tot);
ans2 = solve(b, tot, k);
cout<< (ans2 - ans1) / << endl;
}
return ;
}

代码二(树状数组):

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
#include <vector>
#include <stack>
#include <string>
#include <ctime>
#include <queue>
#define mem0(a) memset(a, 0, sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define eps 0.0000001
#define lowbit(x) ((x) & -(x))
#define memc(a, b) memcpy(a, b, sizeof(b))
#define x_x(a) ((a) * (a))
#define LL long long
#define DB double
#define pi 3.14159265359
#define MD 10000007
#define INF (int)1e9
#define max(a, b) ((a) > (b)? (a) : (b))
using namespace std;
map<int, int> hash;
int nn, tot, arr[], arr0[], c[], a[][], m[];
void init()
{
sort(arr + , arr + + tot);
arr0[] = arr[];
nn = ;
hash[arr0[]] = ;
for(int i = ; i <= tot; i++) {
if(arr[i] != arr[i - ]) {
arr0[++nn] = arr[i];
hash[arr[i]] = nn;
}
}
}
void update(int p, int x)
{
while(p <= nn) {
c[p] += x;
p += lowbit(p);
}
}
void insert(int a[], int n)
{
for(int i = ; i <= n; i++) {
int tmp = hash[a[i]];
update(tmp, );
}
}
int sum(int p)
{
int ans = ;
while(p) {
ans += c[p];
p -= lowbit(p);
}
return ans;
}
int query(int L, int R)
{
return sum(R) - sum(L - );
}
int find(int x)
{
int l = , r = nn;
while(l < r) {
int m = (l + r) >> ;
if(arr0[m] > x) r = m;
else l = m + ;
}
return l;
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
int T;
cin>> T;
while(T--) {
hash.clear();
mem0(c);
int n, k;
cin>> n>> k;
tot = ;
for(int i = ; i <= n; i++) {
cin>> m[i];
for(int j = ; j <= m[i]; j++) {
scanf("%d", &a[i][j]);
arr[++tot] = a[i][j];
}
}
init();
insert(a[], m[]);
LL ans = ;
for(int i = ; i <= n; i++) {
for(int j = ; j <= m[i]; j++) {
int tmp = find(k - a[i][j]);
ans += query(tmp, nn);
}
insert(a[i], m[i]);
}
cout<< ans<< endl;
}
return ;
}

[hdu5101]计数问题的更多相关文章

  1. 一些gcd计数问题

    数论什么的全都忘光了吧QAQ 做了几道简单的题练习一下. bzoj1101: [POI2007]Zap 求有多少对数满足 gcd(x,y)=d, 1<=x<=a, 1<=y<= ...

  2. 扩展Python模块系列(四)----引用计数问题的处理

    承接上文,发现在使用Python C/C++ API扩展Python模块时,总要在各种各样的地方考虑到引用计数问题,稍不留神可能会导致扩展的模块存在内存泄漏.引用计数问题是C语言扩展Python模块最 ...

  3. 置换群、Burnside引理与等价类计数问题

    置换群.Burnside引理与等价类计数问题 标签: 置换群 Burnside引理 置换 说说我对置换的理解,其实就是把一个排列变成另外一个排列.简单来说就是一一映射.而置换群就是置换的集合. 比如\ ...

  4. [HEOI2013]SAO ——计数问题

    题目大意: Welcome to SAO ( Strange and Abnormal Online).这是一个 VR MMORPG, 含有 n 个关卡.但是,挑战不同关卡的顺序是一个很大的问题. 有 ...

  5. cojs 二分图计数问题1-3 题解报告

    OwO 良心的FFT练手题,包含了所有的多项式基本运算呢 其中一部分解法参考了myy的uoj的blog 二分图计数 1: 实际是求所有图的二分图染色方案和 我们不妨枚举这个图中有多少个黑点 在n个点中 ...

  6. LOJ #6089. 小 Y 的背包计数问题

    LOJ #6089. 小 Y 的背包计数问题 神仙题啊orz. 首先把数分成\(<=\sqrt n\)的和\(>\sqrt n\)的两部分. \(>\sqrt n\)的部分因为最多选 ...

  7. 【LOJ6089】小Y的背包计数问题(动态规划)

    [LOJ6089]小Y的背包计数问题(动态规划) 题面 LOJ 题解 神仙题啊. 我们分开考虑不同的物品,按照编号与\(\sqrt n\)的关系分类. 第一类:\(i\le \sqrt n\) 即需要 ...

  8. Project Euler 453 Lattice Quadrilaterals 困难的计数问题

    这是一道很综合的计数问题,对于思维的全面性,解法的过渡性,代码能力,细节处理,计数问题中的各种算法,像gcd.容斥.类欧几里德算法都有考察.在省选模拟赛中做到了这题,然而数据范围是n,m小于等于100 ...

  9. Codeforces 1109D (树的计数问题)

    思路看这篇博客就行了:https://www.cnblogs.com/zhouzhendong/p/CF1109D.html, 讲的很好 今天学到了prufer编码,这是解决树上计数问题的一大利器,博 ...

随机推荐

  1. Laravel joinSub 子查询的写法

    $subQuery = $model::query() ->from('table1 as a') ->getQuery(); $query = $model::query() -> ...

  2. [linux][mysql] 命令更改表结构:添加、删除、修改字段、调整字段顺序

    原文出处:http://www.phpernote.com/MySQL/1120.html 查看表结构: desc tabl_name; show columns fromtable_name: 常用 ...

  3. [半翻] 设计面向DDD的微服务

    这篇文章行文结构对照微软博客, 结合本人意译和多年实践的回顾思考形成此次读书笔记. Domian-driven Design 领域-驱动-设计(DDD)提倡基于(用例相关的现实业务)进行建模. 1. ...

  4. Java中的二分查找

    二分查找:(折半查找) 前提:数组必须是有序的. 思想:每次都猜中间的那个元素,比较大或者小,就能减少一半的元素.思路:A:定义最小索引,最大索引. B:比较出中间索引 C:拿中间索引的值和要查找的元 ...

  5. Python软件定时器APScheduler使用【软件定时器,非操作系统定时器,软件可控的定时器】【用途:定时同步数据库和缓存等】【刘新宇】

    APScheduler使用 APScheduler (advanceded python scheduler)是一款Python开发的定时任务工具. 文档地址 https://apscheduler. ...

  6. Codeforces 1340B Nastya and Scoreboard(dp,贪心)

    题目链接OvO 题目大意   给你\(n\)串数字,\(1\)代表该位置是亮的,\(0\)代表是灭的.你必须修改\(k\)个数字,使某些\(0\)变为\(1\).注意,只能把原来的\(0\)改成\(1 ...

  7. 理解java容器底层原理--手动实现LinkedList

    Node java 中的 LIinkedList 的数据结构是链表,而链表中每一个元素是节点. 我们先定义一下节点: package com.xzlf.collection; public class ...

  8. GC日志分析详解

    点击返回上层目录 原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 GC日志分析详解 以ParallelGC为例,YoungGC日志解释如下 ...

  9. docker企业级镜像仓库Harbor管理

    Harbor概述 Harbor是由VMWare公司开源的容器镜像仓库.事实上,Harbor是在Docker Registry上进行了相应的企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括: ...

  10. 深入理解TCP建立和关闭连接

    建立连接: 理解:窗口和滑动窗口TCP的流量控制TCP使用窗口机制进行流量控制什么是窗口?连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端 接收方发送的确认信息中包含了自 ...