您的位置:首页 > 其它

[hdu5101]计数问题

2014-11-13 15:52 141 查看
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;
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: