[hdu5101]计数问题
2014-11-13 15:52
141 查看
http://acm.hdu.edu.cn/showproblem.php?pid=5101
题目大意:给n个集合,求从两个不同集合里面各取一个数使得它们的和大于给定数的方案数。
ans=从所有数里面取两个数的方案数-从每个集合里面取两个数的方案数(这是关键)
如果不转换也可以这么做,离散一下,然后树状数组统计也行,具体见代码。
代码一:
View Code
题目大意:给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; map<int, int> hash; int nn, tot, arr[220000], arr0[220000], c[220000], a[1200][120], m[1200]; void init() { sort(arr + 1, arr + 1 + tot); arr0[1] = arr[1]; nn = 1; hash[arr0[1]] = 1; for(int i = 2; i <= tot; i++) { if(arr[i] != arr[i - 1]) { 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 = 1; i <= n; i++) { int tmp = hash[a[i]]; update(tmp, 1); } } int sum(int p) { int ans = 0; while(p) { ans += c[p]; p -= lowbit(p); } return ans; } int query(int L, int R) { return sum(R) - sum(L - 1); } int find(int x) { int l = 1, r = nn; while(l < r) { int m = (l + r) >> 1; if(arr0[m] > x) r = m; else l = m + 1; } 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 = 0; for(int i = 1; i <= n; i++) { cin>> m[i]; for(int j = 1; j <= m[i]; j++) { scanf("%d", &a[i][j]); arr[++tot] = a[i][j]; } } init(); insert(a[1], m[1]); LL ans = 0; for(int i = 2; i <= n; i++) { for(int j = 1; j <= m[i]; j++) { int tmp = find(k - a[i][j]); ans += query(tmp, nn); } insert(a[i], m[i]); } cout<< ans<< endl; } return 0; }
View Code
相关文章推荐
- 多重幂计数问题
- [SQL Server]关于标识列从1开始计数的问题
- 字符计数问题
- 正整数中数字1的计数问题 - 简单算法(上)
- 线程、进程内核对象引用计数问题
- 正整数中数字1的计数问题 - 采用分治法快速计算f(n)(下)
- Oracle中较长number型数值的科学计数显示问题
- 计数与排序问题
- 计数问题
- [SQL Server]关于标识列从1开始计数的问题
- Access自动编号字段重新计数问题
- 组件的引用计数问题
- 数字计数问题:计算0~9的每一个数字出现的次数
- POJ 1952 BUY LOW BUY LOWER 【DP】最长降序子序列及其计数问题
- Java如何解决Excel导入文件时科学计数问题
- 序关系计数问题
- (笔记)在Quartus II与ModelSim下仿真,对计数初值的设置问题(ModelSim)(Quartus II)(Verilog)
- Oracle中较长number型数值的科学计数显示问题
- 南京邮电oj 1222序关系计数问题
- 带着5G数据的网站升级(1)--计数我遇到的问题