DynamicSegmentTree
最近尝试了一下动态开点线段树,英文直译就是Dynamic Open Point Segment Tree,太SB了。
就跟之前的主席树写法差不多。
if(!x || x == y) {
x = ++tot;
}
主席树
if(!o) {
o = ++tot;
}
动态开点线段树
实际上当普通线段树用就行了......
例题:洛谷P1908 逆序对
我们可以不离散化,使用动态开点,直接在1e9上开值域线段树。吸氧后堪堪A掉。
// luogu-judger-enable-o2
#include <cstdio> typedef long long LL;
const int N = ; int sum[N * ], tot, ls[N * ], rs[N * ], a[N], root; void add(int L, int R, int l, int r, int &o) {
if(!o) {
o = ++tot;
}
if(L <= l && r <= R) {
sum[o]++;
return;
}
int mid = (l + r) >> ;
if(L <= mid) {
add(L, R, l, mid, ls[o]);
}
if(mid < R) {
add(L, R, mid + , r, rs[o]);
}
sum[o] = sum[ls[o]] + sum[rs[o]];
return;
} int ask(int L, int R, int l, int r, int o) {
if(!o) {
return ;
}
if(L <= l && r <= R) {
return sum[o];
}
int mid = (l + r) >> ;
int ans = ;
if(L <= mid) {
ans += ask(L, R, l, mid, ls[o]);
}
if(mid < R) {
ans += ask(L, R, mid + , r, rs[o]);
}
return ans;
} int main() {
//printf("%d", sizeof(sum) / 1024 / 1024 * 3);
int n, m = 1e9; scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
} LL ans = ;
for(int i = ; i <= n; i++) {
ans += ask(a[i] + , m, , m, );
add(a[i], a[i], , m, root);
}
printf("%lld", ans);
return ;
}
AC代码
例题:洛谷P2471 降雨量
这个题的难点TM在于分类讨论......大毒瘤。
对于未知的位置,我们用一个bool数组维护就行了。
询问的时候查x,y,(x,y)三段,然后暴力讨论.....
#include <cstdio>
#include <algorithm> const int N = , E = 1e9 + ; int root, large[N * ], tot, ls[N * ], rs[N * ];
bool maybe, sure[N * ]; void change(int p, int v, int l, int r, int &o) {
//printf("change : %d %d %d %d \n", p, v, l, r);
//getchar();
if(!o) {
o = ++tot;
}
if(l == r) {
large[o] = v;
sure[o] = ;
return;
}
int mid = l + (r - l) / ;
if(p <= mid) {
change(p, v, l, mid, ls[o]);
}
else {
change(p, v, mid + , r, rs[o]);
}
large[o] = std::max(large[ls[o]], large[rs[o]]);
sure[o] = sure[ls[o]] & sure[rs[o]];
return;
} int ask(int L, int R, int l, int r, int o) {
//printf("%d %d %d %d \n", L, R, l, r);
if(!o) {
maybe = ;
return ;
}
if(L <= l && r <= R) {
if(!sure[o]) {
maybe = ;
}
return large[o];
}
int mid = l + (r - l) / ;
int ans = ;
if(L <= mid) {
ans = std::max(ans, ask(L, R, l, mid, ls[o]));
}
if(mid < R) {
ans = std::max(ans, ask(L, R, mid + , r, rs[o]));
}
return ans;
} int main() {
int n, limit = E << , x, y;
scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%d%d", &x, &y);
change(x + E, y, , limit, root);
}
scanf("%d", &n);
while(n--) {
scanf("%d%d", &y, &x);
if(y == x) {
printf("true\n");
continue;
}
int c = ask(y + E, y + E, , limit, root);
int cc = maybe;
maybe = ;
int d = ask(x + E, x + E, , limit, root);
int dd = maybe;
maybe = ;
//printf("%d %d %d %d \n", c, cc, d, dd); false -> maybe
if(y + == x) {
if(cc || dd){
printf("maybe\n");
}
else {
if(c >= d) {
printf("true\n");
}
else {
printf("false\n");
}
}
continue;
}
int e = ask(y + + E, x - + E, , limit, root);
int ee = maybe;
maybe = ;
//printf("%d %d \n", e, ee);
if(dd) {
if(cc) {
printf("maybe\n");
}
else {
if(e >= c) {
printf("false\n");
}
else {
printf("maybe\n");
}
}
continue;
}
if(cc) {
if(e >= d) {
printf("false\n");
}
else {
printf("maybe\n");
}
continue;
}
if(ee) {
if(e >= d || c < d) {
printf("false\n");
}
else {
printf("maybe\n");
}
continue;
}
if(e >= d || c < d) {
printf("false\n");
}
else {
printf("true\n");
}
} return ;
}
AC代码
DynamicSegmentTree的更多相关文章
随机推荐
- 2017-2018-2 20155224『网络对抗技术』Exp4:恶意代码分析
原理与实践说明 实践目标 监控你自己系统的运行状态,看有没有可疑的程序在运行. 分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysinternals,systr ...
- Kafka查看topic、consumer group状态命令
最近工作中遇到需要使用kafka的场景,测试消费程序启动后,要莫名的过几十秒乃至几分钟才能成功获取到到topic的partition和offset,而后开始消费数据,于是学习了一下查看kafka br ...
- POJ1159
这竟然是IOI虽然是2000年的,但其实也改变不了它水题的本质 我写了两种方法,这里都讲一下吧 考虑记忆化搜索,用f[i][j]表示当区间的左端为i,右端为j时最少要添加多少字符,所以ans就为f[1 ...
- RegExp,实现匹配合法时间(24小时制)的正则表达式
合法时间格式 00:00:00 - 23:59:59 格式分析:H + ":" + M + ":" + S H-分析: 00:00:00 - 09:5 ...
- [JOI2017春季合宿]Port Facility[set、二分图]
题意 你有两个栈,有 \(n\) 个货物,每个货物有一个进栈时间和出栈时间(所有时间的并集是1~2n),问有多少种不同的入栈方案. \(n\le 10^6\) 分析 把每个货物的存在看成区间,相交的区 ...
- 把Excel的数据导入到数据库
将Excel作为数据源,将数据导入数据库,是SSIS的一个简单的应用,下图是示例Excel,数据列是code和name 第一部分,Excel中的数据类型是数值类型 1,使用SSDT创建一个packag ...
- VirtualBox虚拟机怎么导入已经存在的vdi文件
VirtualBox虚拟机怎么导入已经存在的vdi文件 第一章 1.原因 早上一不小心将virtualBox 卸载了,(不知道怎么了, 里面得虚拟机全部都没有了,但是vdi文件还在) 2.解决办法 直 ...
- GitHubDesktop权限问题解决办法
Desktop对于管理仓库非常方便.实用 很多人实用Desktop将仓库项目clone到本地 但是更新后同步时出现了如下权限错误: Error Authentication failed. You m ...
- LeetCode-765.情侣牵手
N 对情侣坐在连续排列的 2N 个座位上,想要牵到对方的手. 计算最少交换座位的次数,以便每对情侣可以并肩坐在一起. 一次交换可选择任意两人,让他们站起来交换座位. 人和座位用 0 到 2N-1 的整 ...
- 怎么用JavaScript写一个区块链?
几乎所有语言都可以编写区块链开发程序.那么如何用JavaScript写一个区块链?以下我将要用JavaScript来创建1个简单的区块链来演示它们的内部到底是怎样工作的.我将会称作SavjeeCoin ...