hdu 5101 Select(树状数组)

题目链接:hdu5101 Select

题目大意:N和K,给定若干组数,要从从不同组中选出连个数和大于K,问说有多少种组成方案。

解题思路:树状数组维护,将所有的数离散化掉对应成树状数组的下标,每次先计算一组,然后再将该组的元素插入到

树状数组中。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long ll;
const int maxn = 1005;
const int maxm = 105;
const int maxs = 1e5 + 1;
#define lowbit(x) ((x)&(-x))

int N, M, cn[maxn], fenw[maxs + 5];
ll K, clas[maxn][maxm];
ll idx[maxs + 5], tmp[maxs + 5];

inline void add(int x, int d) {
    while (x <= maxs) {
        fenw[x] += d;
        x += lowbit(x);
    }
}

inline int sum(int x) {
    int ret = 0;
    while (x) {
        ret += fenw[x];
        x -= lowbit(x);
    }
    return ret;
}

void init () {
    int n = M = 0;
    scanf("%d%I64d", &N, &K);
    memset(cn, 0, sizeof(cn));
    memset(fenw, 0, sizeof(fenw));

    for (int i = 1; i <= N; i++) {
        scanf("%d", &cn[i]);
        for (int j = 0; j < cn[i]; j++) {
            scanf("%I64d", &clas[i][j]);
            tmp[n++] = clas[i][j];
        }
    }

    sort(tmp, tmp + n);
    idx[M++] = tmp[0];
    for (int i = 1; i < n; i++) {
        if (tmp[i] != tmp[i-1])
            idx[M++] = tmp[i];
    }
}

inline int find (ll x) {
    return (lower_bound(idx, idx + M, x) - idx) + 1;
}

void insert(int d) {
    for (int i = 0; i < cn[d]; i++) {
        int pos = find(clas[d][i]);
        add(pos, 1);
    }
}

ll query(int d) {
    ll ret = 0;
    for (int i = 0; i < cn[d]; i++) {
        int pos = find(K - clas[d][i] + 1);
        ret += sum(maxs) - sum(pos-1);
    }
    return ret;
}

int main () {
    int cas;
    scanf("%d", &cas);
    while (cas--) {
        init();

        ll ans = 0;
        insert(1);
        for (int i = 2; i <= N; i++) {
            ans += query(i);
            insert(i);
        }
        printf("%I64d\n", ans);
    }
    return 0;
}
时间: 2024-10-01 10:52:21

hdu 5101 Select(树状数组)的相关文章

HDOJ 5101 Select 树状数组

离散化+树状数组 Select Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1149    Accepted Submission(s): 329 Problem Description One day, Dudu, the most clever boy, heard of ACM/ICPC, which is a very in

HDU Cow Sorting (树状数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2838 Cow Sorting Problem Description Sherlock's N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...100,000. Since grumpy cow

hdu 5193 分块 树状数组 逆序对

题意: 给出n个数,a1,a2,a3,...,an,给出m个修改,每个修改往数组的某个位置后面插入一个数,或者把某个位置上的数移除.求每次修改后逆序对的个数. 限制: 1 <= n,m <= 20000; 1 <= ai <= n 思路: 插入和删除用分块来处理,块与块之间用双向链表来维护,每一块用树状数组来求小于某个数的数有多少个. 外层可以使用分块维护下标,这样添加和删除元素的时候,也很方便,直接暴力.查找权值个数时,使用树状数组比较方便.内层通过树状数组维护权值. 每次更新即

HDU 5493 Queue 树状数组

Queue Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5493 Description N people numbered from 1 to N are waiting in a bank for service. They all stand in a queue, but the queue never moves. It is lunch time now,

hdu 4455 Substrings(树状数组+递推)

题目链接:hdu 4455 Substrings 题目大意:给定一个长度为N的序列,现在有Q次询问,每次给定一个w,表示长度,输出序列中长度为w的连续子序列 的权值和.序列的权值表示序列中不同元素的个数. 解题思路:递推,先预处理处每个位置和前面相同的数据的最短距离P.dp[i]表示说长度为i子序列的权值和,dp[i+1] = dp[i] + v - c.v为[i+1~N]中P值大于i的个数,我们可以看作将长度为i的子序列长度向后增加1,那么v则为增加长度带来 的权值增加值,c则是最后一个长度为

POJ 2352 &amp;&amp; HDU 1541 Stars (树状数组)

一开始想,总感觉是DP,可是最后什么都没想到.还暴力的交了一发. 然后开始写线段树,结果超时.感觉自己线段树的写法有问题.改天再写.先把树状数组的写法贴出来吧. ~~~~~~~~~~~~~~~~~~~~~~~~ 树状数组不懂的去看刘汝佳的大白书,那个图画得很清楚. 题目大意:星星的坐标以y递增的顺序给出,这些点的左下方的点数代表这个点的级数,问0~N-1的级数有多少个?其实y根本木有用. 题目链接:http://poj.org/problem?id=2352 http://acm.hdu.edu

hdu 4031(树状数组+辅助数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4031 Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 1890    Accepted Submission(s): 554 Problem Description Today is the 10th Annual of "S

HDU 2689Sort it 树状数组 逆序对

Sort it Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4110    Accepted Submission(s): 2920 Problem Description You want to processe a sequence of n distinct integers by swapping two adjacent s

HDU 2838 (DP+树状数组维护带权排序)

Reference: http://blog.csdn.net/me4546/article/details/6333225 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2838 题目大意:每头牛有个愤怒值,每次交换相邻两个数进行升序排序,$cost=val_{1}+val_{2}$,求$\min \sum cost_{i}$ 解题思路: 按输入顺序DP: 第i的值val的最小cost=当前数的逆序数个数*val+当前数的逆序数和 相当于每次只