您的位置:首页 > 其它

[HDOJ4325]Flowers(树状数组 离散化)

2016-04-25 21:21 323 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4325

关于离散化的简介:http://blog.csdn.net/gokou_ruri/article/details/7723378

假如数据太大,无法作为数组下标来保存对应的属性而采取的一种方法。只需要关注相对大小即可。

我们记下所有的时间数据,再排序。通过二分查找快速定位元素的位置,然后在线段树或者树状数组上仅仅更新这个映射过后的下标位置。因为不需要从线段树或树状数组上直接获取数据(单纯的线段树或树状数组本身是没有意义的,需要搭配相应的数据操作才可以使其称之为线段树或树状数组),也就是说我们更新和查询都是要通过这样一次定位。这样可以解决空间不足的问题。排序后要去重,否则更新到时候可能会更新两次。

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>

using namespace std;

typedef struct Node {
int s;
int t;
}Node;

const int maxn = 1000010;
int n, m, cnt, tot;
int wt[maxn<<2];
int bit[maxn];
int ask[maxn];
Node f[maxn];

int lowbit(int x) {
return x & (-x);
}

void add(int i, int x) {
while(i <= cnt) {
bit[i] += x;
i += lowbit(i);
}
}

int sum(int i) {
int s = 0;
while(i > 0) {
s += bit[i];
i -= lowbit(i);
}
return s;
}

int bs(int v) {
int ll = 0, rr = cnt - 1;
int mm;
while(ll <= rr) {
mm = (ll + rr) >> 1;
if(wt[mm] == v) return mm;
if(wt[mm] > v) rr = mm - 1;
if(wt[mm] < v) ll = mm + 1;
}
return -1;
}

inline bool scan_d(int &num) {
char in;bool IsN=false;
in=getchar();
if(in==EOF) return false;
while(in!='-'&&(in<'0'||in>'9')) in=getchar();
if(in=='-'){ IsN=true;num=0;}
else num=in-'0';
while(in=getchar(),in>='0'&&in<='9'){
num*=10,num+=in-'0';
}
if(IsN) num=-num;
return true;
}

int main() {
// freopen("in", "r", stdin);
int T, _ = 1;
scan_d(T);
while(T--) {
tot = 0;
memset(bit, 0, sizeof(bit));
scan_d(n); scan_d(m);
for(int i = 1; i <= n; i++) {
scan_d(f[i].s); scan_d(f[i].t);
wt[tot++] = f[i].s; wt[tot++] = f[i].t;
}
for(int i = 1; i <= m; i++) {
scan_d(ask[i]);
wt[tot++] = ask[i];
}
sort(wt, wt+tot);
// int tot = unique(wt,wt+tot) - wt;
cnt = 1;
for(int i = 1; i < tot; i++) {
if(wt[i] != wt[i-1]) wt[cnt++] = wt[i];
}
for(int i = 1; i <= n; i++) {
int x = bs(f[i].s) + 1;
int y = bs(f[i].t) + 1;
add(x, 1);
add(y+1, -1);
}
printf("Case #%d:\n", _++);
for(int i = 1; i <= m; i++) {
int ans = bs(ask[i]) + 1;
printf("%d\n", sum(ans));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: