博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 6534 Chika and Friendly Pairs (树状数组 离散化 莫队)
阅读量:5050 次
发布时间:2019-06-12

本文共 2291 字,大约阅读时间需要 7 分钟。

树状数组 离散化 莫队

求[L,R]内有多少对(i, j)满足|a[i] - a[j]| <= K,我们转换为求[a[i] - k - 1, a[i] + k]的个数

离散化处理a[i], a[i] - k, a[i] + k的下标(二分处理)

然后莫队查询,用树状数组维护这些数,实现区间查询,区间修改

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define rep(i, s, e) for(int i = s; i < e; ++i)#define P pair
#define INF 0x3f3f3f3fusing namespace std;typedef long long ll;static const int N = 35;static const int MAX_N = 27005;static const ll Mod = 1e9 + 7;int a[MAX_N], b[MAX_N * 3], c[MAX_N * 3], suml[MAX_N], sumr[MAX_N], rev[MAX_N];int maxv;struct Query{ int l, r, pos, id; bool operator < (const Query &rhs)const{ return (pos ^ rhs.pos) ? l < rhs.l : (pos & 1) ? r < rhs.r : r > rhs.r; }}q[MAX_N];int lowbit(int x){ return x & (-x);}void update(int p, int v){ for(int i = p; i <= maxv; i += lowbit(i)) c[i] += v;}int query(int p){ int rt = 0; for(int i = p; i; i -= lowbit(i)) rt += c[i]; return rt;}void solve(){// freopen("input.txt", "r", stdin);// freopen("output.txt", "w", stdout); int n, m, k; scanf("%d%d%d", &n, &m, &k); maxv = n * 3; int cnt = 0; for(int i = 1; i <= n; ++i){ scanf("%d", &a[i]); b[++cnt] = a[i] - k; b[++cnt] = a[i]; b[++cnt] = a[i] + k; } int block = (int)sqrt(n); for(int i = 1; i <= m; ++i){ scanf("%d%d", &q[i].l, &q[i].r); q[i].id = i; q[i].pos = (q[i].l - 1) / block + 1; } sort(b + 1, b + cnt + 1); int cur = unique(b + 1, b + cnt + 1) - b - 1; for(int i = 1; i <= n; ++i){ suml[i] = lower_bound(b + 1, b + cur + 1, a[i] - k) - b; sumr[i] = lower_bound(b + 1, b + cur + 1, a[i] + k) - b; a[i] = lower_bound(b + 1, b + cur + 1, a[i]) - b; } sort(q + 1, q + m + 1); int l = 1, r = 0; int ans = 0; for(int i = 1; i <= m; ++i){ while(l < q[i].l){ update(a[l], -1); ans -= query(sumr[l]) - query(suml[l] - 1); ++l; } while(l > q[i].l){ --l; ans += query(sumr[l]) - query(suml[l] - 1); update(a[l], 1); } while(r > q[i].r){ update(a[r], -1); ans -= query(sumr[r]) - query(suml[r] - 1); --r; } while(r < q[i].r){ ++r; ans += query(sumr[r]) - query(suml[r] - 1); update(a[r], 1); } rev[q[i].id] = ans; } for(int i = 1; i <= m; ++i) printf("%d\n", rev[i]);}int main() { solve(); return 0;}
View Code

 

转载于:https://www.cnblogs.com/xorxor/p/10928297.html

你可能感兴趣的文章
关于现在,关于未来
查看>>
day9 重写父类的方法
查看>>
你应该知道的四种优秀架构
查看>>
php 支持8种基本的数据类型
查看>>
保卫"木叶",从火影剧情看网站攻防的演变
查看>>
大数据学习——linux常用命令(三)
查看>>
linux下memcache的运用,和php结合小案例。
查看>>
COGS 1298. 通讯问题
查看>>
ip地址
查看>>
理解使用 JavaScript 构建 Metro 应用
查看>>
c++ std::string.c_str()
查看>>
i++和++i
查看>>
MFC六大核心机制
查看>>
iPhone 屏幕分辨率
查看>>
thinkPHP 模板中变量的使用
查看>>
java 的访问权限控制
查看>>
BZOJ 3676: [Apio2014]回文串
查看>>
在C#4.0中使用NPLOT
查看>>
用FPGA驱动ov7670摄像头用tft9328显示
查看>>
图像增强
查看>>