珂朵莉树(odt老司机树)
传送门
题意:对于一段区间一共有四种操作:
题解:珂朵莉树板题
珂朵莉树,又称Old Driver Tree(ODT)。是一种基于std::set
的暴力数据结构。
关键操作:推平一段区间,使一整段区间内的东西变得一样。保证数据随机。
这道题里,这样定义珂朵莉树的节点:
struct node
{int l,r;mutable LL v;node(int L, int R=-1, LL V=0):l(L), r(R), v(V) {}bool operator<(const node& o) const{return l < o.l;}
};
这样的一个节点表示[l,r]内的所有数都是v。需要注意的是mutable
,意为易变的,不定的。它对v
的修饰,使得可以在add
操作中修改v
的值。没有它的修饰会在add
函数里导致CE。
核心操作:split
#define IT set<node>::iterator
IT split(int pos)
{IT it = s.lower_bound(node(pos));if (it != s.end() && it->l == pos) return it;--it;int L = it->l, R = it->r;LL V = it->v;s.erase(it);s.insert(node(L, pos-1, V));return s.insert(node(pos, R, V)).first;
}
最后一句插入后半段,返回后半段的迭代器。这里利用了pair<iterator,bool> insert (const value_type& val)
的返回值。
推平操作:assign
void assign(int l, int r, LL val=0)
{IT itl = split(l),itr = split(r+1);s.erase(itl, itr);s.insert(node(l, r, val));
}
附上代码:
#include<cstdio>
#include<set>
#include<vector>
#include<utility>
#include<algorithm>
#define IT set<node>::iteratorusing std::set;
using std::vector;
using std::pair;typedef long long LL;
const int MOD7 = 1e9 + 7;
const int MOD9 = 1e9 + 9;
const int imax_n = 1e5 + 7;LL pow(LL a, LL b, LL mod)
{LL res = 1;LL ans = a % mod;while (b){if (b&1) res = res * ans % mod;ans = ans * ans % mod;b>>=1;}return res;
}struct node
{int l,r;mutable LL v;node(int L, int R=-1, LL V=0):l(L), r(R), v(V) {}bool operator<(const node& o) const{return l < o.l;}
};set<node> s;IT split(int pos)
{IT it = s.lower_bound(node(pos));if (it != s.end() && it->l == pos) return it;--it;int L = it->l, R = it->r;LL V = it->v;s.erase(it);s.insert(node(L, pos-1, V));return s.insert(node(pos, R, V)).first;
}void add(int l, int r, LL val=1)
{IT itl = split(l),itr = split(r+1);for (; itl != itr; ++itl) itl->v += val;
}void assign_val(int l, int r, LL val=0)
{IT itl = split(l),itr = split(r+1);s.erase(itl, itr);s.insert(node(l, r, val));
}LL rank(int l, int r, int k)
{vector<pair<LL, int> > vp;IT itl = split(l),itr = split(r+1);vp.clear();for (; itl != itr; ++itl)vp.push_back(pair<LL,int>(itl->v, itl->r - itl->l + 1));std::sort(vp.begin(), vp.end());for (vector<pair<LL,int> >::iterator it=vp.begin();it!=vp.end();++it){k -= it->second;if (k <= 0) return it->first;}return -1LL;
}LL sum(int l, int r, int ex, int mod)
{IT itl = split(l),itr = split(r+1);LL res = 0;for (; itl != itr; ++itl)res = (res + (LL)(itl->r - itl->l + 1) * pow(itl->v, LL(ex), LL(mod))) % mod;return res;
}int n, m;
LL seed, vmax;LL rnd()
{LL ret = seed;seed = (seed * 7 + 13) % MOD7;return ret;
}LL a[imax_n];int main()
{scanf("%d %d %lld %lld",&n,&m,&seed,&vmax);for (int i=1; i<=n; ++i){a[i] = (rnd() % vmax) + 1;s.insert(node(i,i,a[i]));}s.insert(node(n+1, n+1, 0));int lines = 0;for (int i =1; i <= m; ++i){int op = int(rnd() % 4) + 1;int l = int(rnd() % n) + 1;int r = int(rnd() % n) + 1;if (l > r)std::swap(l,r);int x, y;if (op == 3)x = int(rnd() % (r-l+1)) + 1;elsex = int(rnd() % vmax) +1;if (op == 4)y = int(rnd() % vmax) + 1;if (op == 1)add(l, r, LL(x));else if (op == 2)assign_val(l, r, LL(x));else if (op == 3)printf("%lld\n",rank(l, r, x));elseprintf("%lld\n",sum(l, r, x, y));}return 0;
}
珂朵莉树(odt老司机树)相关推荐
- [转]我的数据结构不可能这么可爱!——珂朵莉树(ODT)详解
参考资料: Chtholly Tree (珂朵莉树) (应某毒瘤要求,删除链接,需要者自行去Bilibili搜索) 毒瘤数据结构之珂朵莉树 在全是珂学家的珂谷,你却不知道珂朵莉树?来跟诗乃一起学习珂朵 ...
- 我的算法不可能这么简单—珂朵莉树
文章目录 进入正题 珂朵莉树的起源 题目简述 题目分析 珂朵莉树的实现 萌新三连 1.明明查询的右端点是12,但是要split(13)呢? 2.为什么要先分裂右端点,然后再分裂左端点呢? 3.获取到区 ...
- 牛客练习赛7 E 珂朵莉的数列
珂朵莉的数列 思路: 树状数组+高精度 离散化不知道哪里写错了,一直wa,最后用二分写的离散化 哪位路过大神可以帮我看看原来的那个离散化错在哪里啊 通过代码: import java.math.Big ...
- 浅谈珂朵莉树(ODT)
前言 珂学家狂喜( 文章目录 前言 一.珂朵莉树来源 二.珂朵莉树 1.珂朵莉树有什么用? 2.原理是什么? a.存储 b.分割结点 c.推平 d.剩余操作 3.复杂度分析 三.珂朵莉树例题 1.P4 ...
- 珂朵莉树/ODT 学习笔记
珂朵莉树/ODT 学习笔记 起源自 CF896C.珂朵莉yyds! 核心思想 把值相同的区间合并成一个结点保存在 set 里面. 用处 骗分.只要是有区间赋值操作的数据结构题都可以用来骗分.在数据随机 ...
- [python刷题模板] 珂朵莉树 ODT (基于支持随机访问的跳表
[python刷题模板] 珂朵莉树 ODT (基于支持随机访问的跳表) 一. 算法&数据结构 1. 描述 2. 复杂度分析 3. 常见应用 4. 常用优化 二. 模板代码 0. 区间推平(lg ...
- [python刷题模板] 珂朵莉树 ODT(20220928弃用,请看新文)
[python刷题模板] 珂朵莉树 ODT (基于SortedList 20220928弃用,请看新文) 一. 算法&数据结构 1. 描述 2. 复杂度分析 3. 常见应用 4. 常用优化 二 ...
- 【日志】珂学——珂朵莉树
珂朵莉树 (珂学) 珂朵莉树(或者老司机树)起源于CF896C. 由于之前做到每一组数据都要另外开数据结构,所以现在一些东西就会写为class包装 前置知识点 STL中set的使用(list也行,但是 ...
- codeforces 915 E 896 C 珂朵莉树
珂朵莉树(Chtholly Tree),一种基于std::set的暴力数据结构,是由某毒瘤在2017年的一场CF比赛中提出的数据结构,原名老司机树(Old Driver Tree,ODT).由于第一个 ...
最新文章
- android 添加头参数,Retrofit添加header参数的几种方法
- 【Python】进制转换
- 用ASP.NETCore构建可检测的高可用服务
- Spring经典面试题和答案
- Dubbo在互金行业的应用
- 科创板注册获批,优刻得将成为“公有云第一股”
- 3 MM配置-企业结构-定义-定义库存地点
- 2016年4月计算机组成原理试题答案,2019年4月成人自考计算机组成原理真题及答案解析...
- ASP.NET 3.5核心编程学习笔记(17):基于数据源的数据绑定
- 深圳CPDA数据分析认证:数据分析知识很难学么?
- 小程序加入人脸识别_微信小程序怎么实现人脸识别
- Controller数据导出Excel 详细教程
- 一款开源的支持离线的支持MarkDown的优秀笔记软件----思源笔记
- APACHE架构WEB服务器
- 郑捷《机器学习算法原理与编程实践》学习笔记(第四章 推荐系统原理)(一)推荐系统概述...
- 飞鹅云打印机api接口asp版,asp源码对接飞鹅云小票打印机
- Summernote 上传图片至 SMMS 图床 Api
- 令人垂涎的武汉八大名吃
- 神州租车——为用户提供精细化租车服务
- access tempvars 宏_Access数据库教程之使用常用对象来加快Access 2007数据库三