最近尝试了一下动态开点线段树,英文直译就是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的更多相关文章

随机推荐

  1. Huploadify V2.1+ SpringMVC上传文件的实现

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  2. 20155339 Exp7 网络欺诈防范

    20155339 Exp7 网络欺诈防范 .基础问题回答 (1)通常在什么场景下容易受到DNS spoof攻击 当连接局域网的时候应该最容易被攻击,比如说连接了一些不清楚是什么的WiFi其实是很容易收 ...

  3. 小内存VPS apache并发控制参数prefork调优

    小内存VPS优化(使用wdcp lnamp一键包安装环境的情况下): 1.主要优化perfork模式下几个参数,防止开启过多的httpd进程占用大量内存导致内存满:在wdcp下修改的httpd配置文件 ...

  4. 11、Dockerfile实战-Tomcat

    一.编写Dockerfile 具体步骤这里不再细说,直接看Dockerfile文件: FROM centos:7 MAINTAINER QUNXUE ENV VERSION=8.0.46 RUN yu ...

  5. linux重启tomcat的shell脚本

    基本思路: 先检查待重启的tomcat的进程是否存在 存在则执行shutdown. 然后再次检查进程是否还存在,不存在则执行kill 然后删除工作空间及10天前的日志. 最后执行启动. #!/bin/ ...

  6. TimelineJS JSON 数据格式 - 译文 [原创]

    TimelineJS 是用于绘制时间轴的 Javascript 开源脚本,目前是 TimelineJS3 版.参阅 https://github.com/NUKnightLab/TimelineJS3 ...

  7. Notes of Daily Scrum Meeting(12.8)

    今日团队任务总结: 团队成员 今日团队工作 陈少杰 使用例子对json数据进行解析 王迪 确定搜索功能的接口 金鑫 对布局文件进行协助修改 雷元勇 开始进行搜索功能的代码实现 高孟烨 按照学长的样本对 ...

  8. Linux第一章读书笔记

    一.Linux历史 Unix强大的根本原因: 1.简洁,仅仅提供几百个系统调用并且有一个非常明确的设计目的 2.文件对待所有东西,通过一套相同的系统调用接口来进行对数据和设备的操作 3.由于用C语言编 ...

  9. Linux第五周学习总结——扒开系统调用的三层皮(下

    Linux第五周学习总结--扒开系统调用的三层皮(下) 作者:刘浩晨 [原创作品转载请注明出处] <Linux内核分析>MOOC课程http://mooc.study.163.com/co ...

  10. 作业三:LINUX内核的启动过程

    作业三:LINUX内核的启动过程 一.使用GDB跟踪内核从start_kernel到init进程启动(附实验截图) (一)使用自己的Linux系统环境搭建MenuOS的过程 下载内核源代码编译内核 c ...