最近尝试了一下动态开点线段树,英文直译就是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. C# 文本转语音朗读

    1. 利用DONET框架自带的 SpeechSynthesizer ,缺点是没有感情色彩,抑扬顿挫等. using System; using System.Collections.Generic; ...

  2. WPF Get jiayuan outbox list(send mail box)

      Request URL: http://www.jiayuan.com/msg/outbox/list.php Request Method: POST form data: type=all&a ...

  3. 网络对抗技术 2017-2018-2 20152515 Exp4 恶意代码分析

    1.实验后回答问题 (1)如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪些,用什么方法来监控. 答:- 我会使用sysmon工具来 ...

  4. PostgreSQL索引页

    磨砺技术珠矶,践行数据之道,追求卓越价值   [作者 高健@博客园  luckyjackgao@gmail.com] 本页目的,是起到索引其他所有本人所写文档的作用: 分类一:PostgreSQL基础 ...

  5. 【转载】C++文件读写详解(ofstream,ifstream,fstream)

    原文:http://blog.csdn.net/kingstar158/article/details/6859379 在看C++编程思想中,每个练习基本都是使用ofstream,ifstream,f ...

  6. CS299笔记:广义线性模型

    指数分布族 我们称一类分布属于指数分布族(exponential family distribution),如果它的分布函数可以写成以下的形式: \[ \begin{equation} p(y;\et ...

  7. C语言学习之枚举类型

    前言 枚举(enum)类型是计算机编程语言中的一种数据类型.枚举类型:在实际问题中,有些变量的取值被限定在一个有限的范围内.例如,一个星期内只有七天,一年只有十二个月,一个班每周有六门课程等等.如果把 ...

  8. Python_xlutils.copy

    import xlrd import xlwt from xlutils.copy import copy # 读取工作簿 objWB = xlrd.open_workbook(r'C:\Users\ ...

  9. 【大数据实战】将普通文本文件导入ElasticSearch

    以<刑法>文本.txt为例. 一.格式化数据 1,首先,ElasticSearch只能接收格式化的数据,所以,我们需要将文本文件转换为格式化的数据---json. 下图为未处理的文本文件. ...

  10. 微软职位内部推荐-Sr. SW Engineer for Privacy Id

    微软近期Open的职位: Job posting title: Senior Software Engineer for Privacy Identification Profession: Engi ...