博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SCUT - G - 魔法项链 - 树状数组
阅读量:4681 次
发布时间:2019-06-09

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

很久以前做的一个东西,当时是对R排序之后树状数组暴力统计当前区间的前缀和。每有一个元素出现在R的范围内,就解除他的同样元素的影响,在他上一个同样元素曾经+1的位置给他-1。因为已经对R进行排序了,下一个询问一定会更容易包含后面出现的那一个。

今天又演了居然想尺取,做不到做不到,L是会不断变化的,不满足尺取的条件。

然后重写的时候发现

last[a[R]]=R++;

last[a[R]]=R;++R;

并不等价。

看来会改变的同一个变量最好只在一句话中出现一次。

#include
using namespace std;typedef long long ll;struct Query { int l, r, id;} q[1000005];bool cmp1(const Query& q1, const Query& q2) { return q1.r != q2.r ? q1.r < q2.r : q1.l < q2.l;}int ans[1000005];int n, m, a[1000005];int last[1000005], cnt;int bit[1000005];inline int Sum(int x) { int res = 0; for(; x; x -= x & -x) res += bit[x]; return res;}inline void Add(int x, int v) { for(; x <= n; x += x & -x) bit[x] += v;}int main() {#ifdef Yinku freopen("Yinku.in", "r", stdin);#endif // Yinku scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); scanf("%d", &m); for(int i = 1; i <= m; ++i) { scanf("%d%d", &q[i].l, &q[i].r); q[i].id = i; } sort(q + 1, q + 1 + m, cmp1); int R = 1; for(int i = 1; i <= m; ++i) { while(R <= q[i].r) { if(last[a[R]]) Add(last[a[R]], -1); Add(R, 1); last[a[R]] = R; ++R; } ans[q[i].id] = Sum(q[i].r) - Sum(q[i].l - 1); } for(int i = 1; i <= m; ++i) printf("%d\n", ans[i]); return 0;}

在不引起混淆的情况下,使用运算符重载会比使用外部cmp快10%。

#include
using namespace std;typedef long long ll;struct Query { int l, r, id; bool operator<(const Query& q2) { return r < q2.r; }} q[1000005];int ans[1000005];int n, m, a[1000005];int last[1000005], cnt;int bit[1000005];inline int Sum(int x) { int res = 0; for(; x; x -= x & -x) res += bit[x]; return res;}inline void Add(int x, int v) { for(; x <= n; x += x & -x) bit[x] += v;}int main() {#ifdef Yinku freopen("Yinku.in", "r", stdin);#endif // Yinku scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); scanf("%d", &m); for(int i = 1; i <= m; ++i) { scanf("%d%d", &q[i].l, &q[i].r); q[i].id = i; } sort(q + 1, q + 1 + m); int R = 1; for(int i = 1; i <= m; ++i) { while(R <= q[i].r) { if(last[a[R]]) Add(last[a[R]], -1); Add(R, 1); last[a[R]] = R; ++R; } ans[q[i].id] = Sum(q[i].r) - Sum(q[i].l - 1); } for(int i = 1; i <= m; ++i) printf("%d\n", ans[i]); return 0;}

转载于:https://www.cnblogs.com/Yinku/p/11343038.html

你可能感兴趣的文章
敏捷开发笔记
查看>>
学前班
查看>>
关于自关联1
查看>>
hdu-1814(2-sat)
查看>>
谷歌浏览器,添加默认搜索引擎的搜索地址
查看>>
数据结构化与保存
查看>>
为什么需要Docker?
查看>>
国内5家云服务厂商 HTTPS 安全性测试横向对比
查看>>
how to control project
查看>>
转 python新手容易犯的6个错误
查看>>
第四节 -- 列表
查看>>
决策树
查看>>
团队作业
查看>>
如何避免在简单业务逻辑上面的细节上面出错
查看>>
大型网站高并发的架构演变图-摘自网络
查看>>
8丶运行及总结
查看>>
如何理解一台服务器可以绑定多个ip,一个ip可以绑定多个域名
查看>>
改进delphi中的RoundTo函数
查看>>
Microsoft Visual SourceSafe使用经验
查看>>
威尔逊定理及证明
查看>>