这里介绍以个小$trick$,民间流传为$Old Driver Tree$,实质上就是$set$维护线段。

我们将所有连续一段权值相同的序列合并成一条线段,扔到$set$里去,于是$set$里的所有线段的并就是原序列,并且都不相交。

我们在操作的时候很暴力,每次把$[l, r]$的线段抠出来,暴力枚举一遍算答案。对于每一个非区间赋值的操作,最多断两条线段,新加两条线段。

实现起来很方便,思路也非常简单,但是局限性也很明显,因为其复杂度是基于随机的,并且必须存在区间赋值的操作。

但$set$维护线段的技巧还是很常见的,我用$set$和$map$都实现的一遍,发现这里用$map$相当好写。

$set$的实现:

#include <set>
#include <cstdio>
#include <algorithm>
using namespace std; typedef long long LL;
const int N = ; int n, m, vmax, tp;
pair<LL, int> st[N]; struct Seg {
int l, r; LL v;
friend bool operator < (Seg a, Seg b) {
return (a.l != b.l)? (a.l < b.l) : (a.r < b.r);
}
};
multiset<Seg> S;
typedef multiset<Seg>::iterator Saber; LL Pow(LL x, int b, int p, LL re = ) {
for (x %= p; b; b >>= , x = x * x % p)
if (b & ) re = re * x % p;
return re;
} namespace R {
const int mod = 1e9 + ;
int seed, ret;
int rnd() {
ret = seed;
seed = (seed * 7LL + ) % mod;
return ret;
}
} int main() {
scanf("%d%d%d%d", &n, &m, &R::seed, &vmax);
for (int i = ; i <= n; ++i)
S.insert((Seg){ i, i, R::rnd() % vmax + });
for (int op, l, r, x, y; m; --m) {
op = (R::rnd() & ) + ;
l = R::rnd() % n + ;
r = R::rnd() % n + ;
if (l > r) swap(l, r);
if (op == ) x = R::rnd() % (r - l + ) + ;
else x = R::rnd() % vmax + ;
if (op == ) y = R::rnd() % vmax + ; Saber p = --S.lower_bound((Seg){ l + , , });
Saber q = --S.lower_bound((Seg){ r + , , });
if ((*p).l < l) S.insert((Seg){ (*p).l, l - , (*p).v });
if (r < (*q).r) S.insert((Seg){ r + , (*q).r, (*q).v });
if (op == ) {
for (Saber z = p, rin; z != q; ) {
rin = z; ++z;
S.erase(rin);
}
S.erase(q);
S.insert((Seg){ l, r, x });
continue;
}
Saber np, nq;
if (p == q) {
np = nq = S.insert((Seg){ l, r, (*p).v });
S.erase(p);
} else {
np = S.insert((Seg){ l, (*p).r, (*p).v });
nq = S.insert((Seg){ (*q).l, r, (*q).v });
S.erase(p); S.erase(q);
}
if (op == ) {
Seg ins;
for (Saber z = np, rin; z != nq; ) {
rin = z; ++z;
ins = *rin; ins.v += x;
S.erase(rin); S.insert(ins);
}
ins = *nq; ins.v += x;
S.erase(nq); S.insert(ins);
}
if (op == ) {
tp = ;
for (Saber z = np; z != nq; ++z)
st[++tp] = make_pair((*z).v, (*z).r - (*z).l + );
st[++tp] = make_pair((*nq).v, (*nq).r - (*nq).l + );
sort(st + , st + + tp);
for (int i = ; i <= tp; x -= st[i].second, ++i) {
if (st[i].second >= x) {
printf("%lld\n", st[i].first);
x = ;
break;
}
}
if (x > ) {
puts("I love you, love you forever.");
return ;
}
}
if (op == ) {
int ans = ;
for (Saber z = np; z != nq; ++z)
ans = (ans + Pow((*z).v, x, y) * ((*z).r - (*z).l + )) % y;
ans = (ans + Pow((*nq).v, x, y) * ((*nq).r - (*nq).l + )) % y;
printf("%d\n", ans);
}
} return ;
}

$map$的实现:

#include <map>
#include <cstdio>
#include <algorithm>
using namespace std; typedef long long LL;
const int N = ; int n, m, vmax, tp;
pair<LL, int> st[N];
map<int, LL> M; LL Pow(LL x, int b, int p, LL re = ) {
for (x %= p; b; b >>= , x = x * x % p)
if (b & ) re = re * x % p;
return re;
} namespace R {
const int mod = 1e9 + ;
int seed, ret;
int rnd() {
ret = seed;
seed = (seed * 7LL + ) % mod;
return ret;
}
} int main() {
scanf("%d%d%d%d", &n, &m, &R::seed, &vmax);
for (int i = ; i <= n; ++i)
M[i] = R::rnd() % vmax + ;
M[n + ] = ;
for (int op, l, r, x, y; m; --m) {
op = (R::rnd() & ) + ;
l = R::rnd() % n + ;
r = R::rnd() % n + ;
if (l > r) swap(l, r);
if (op == ) x = R::rnd() % (r - l + ) + ;
else x = R::rnd() % vmax + ;
if (op == ) y = R::rnd() % vmax + ; auto p = --M.upper_bound(l);
auto q = M.upper_bound(r);
if (p->first < l) M[l] = p->second, ++p;
if (r + < q->first) --q, M[r + ] = q->second, ++q;
if (op == ) {
for (; p != q; ++p) p->second += x;
}
if (op == ) {
while (p != q) M.erase(p++);
M[l] = x;
}
if (op == ) {
tp = ;
for (auto rin = p; p != q; ++p) {
st[++tp] = { p->second, (++rin)->first - p->first };
}
sort(st + , st + + tp);
for (int i = ; i <= tp; x -= st[i].second, ++i) {
if (x <= st[i].second) {
printf("%lld\n", st[i].first);
break;
}
}
}
if (op == ) {
int ans = ;
for (auto rin = p; p != q; ++p) {
ans = (ans + Pow(p->second, x, y) * ((++rin)->first - p->first)) % y;
}
printf("%d\n", ans);
}
} return ;
}

【Cf #449 C】Willem, Chtholly and Seniorious(set维护线段)的更多相关文章

  1. CF&&CC百套计划1 Codeforces Round #449 C. Willem, Chtholly and Seniorious (Old Driver Tree)

    http://codeforces.com/problemset/problem/896/C 题意: 对于一个随机序列,执行以下操作: 区间赋值 区间加 区间求第k小 区间求k次幂的和 对于随机序列, ...

  2. Codeforces Round #449 (Div. 1) Willem, Chtholly and Seniorious (ODT维护)

    题意 给你一个长为 \(n\) 的序列 \(a_i\) 需要支持四个操作. \(1~l~r~x:\) 把 \(i \in [l, r]\) 的 \(a_i\) 加 \(x\) . \(2~l~r~x: ...

  3. Willem, Chtholly and Seniorious

    Willem, Chtholly and Seniorious https://codeforces.com/contest/897/problem/E time limit per test 2 s ...

  4. Codeforces Round #449 (Div. 1)C - Willem, Chtholly and Seniorious

    ODT(主要特征就是推平一段区间) 其实就是用set来维护三元组,因为数据随机所以可以证明复杂度不超过O(NlogN),其他的都是暴力维护 主要操作是split,把区间分成两个,用lowerbound ...

  5. 【ODT】cf896C - Willem, Chtholly and Seniorious

    仿佛没用过std::set Seniorious has n pieces of talisman. Willem puts them in a line, the i-th of which is ...

  6. [Codeforces896C] Willem, Chtholly and Seniorious (ODT-珂朵莉树)

    无聊学了一下珂朵莉树 珂朵莉树好哇,是可以维护区间x次方和查询的高效数据结构. 思想大致就是一个暴力(相对而言)的树形数据结构 lxl毒瘤太强了,发明了ODT算法(Old Driver Tree老司机 ...

  7. [CF896C]Willem, Chtholly and Seniorious(珂朵莉树)

    https://www.cnblogs.com/WAMonster/p/10181214.html 主要用于支持含有较难维护的区间操作与查询的问题,要求其中区间赋值操作(assign())是纯随机的. ...

  8. 2019.01.19 codeforces896C.Willem, Chtholly and Seniorious(ODT)

    传送门 ODTODTODT出处(万恶之源) 题目简述: 区间赋值 区间加 区间所有数k次方和 区间第k小 思路:直接上ODTODTODT. 不会的点这里 代码: #include<bits/st ...

  9. cf896C. Willem, Chtholly and Seniorious(ODT)

    题意 题目链接 Sol ODT板子题.就是用set维护连续段的大暴力.. 然鹅我抄的板子本题RE提交AC??.. 具体来说,用50 50 658073485 946088556这个数据测试下面的代码, ...

随机推荐

  1. DICOM 协议学习笔记之 What is DICOM

    什么是DICOM? Dicom (Digital Imaging and Communications in Medicine)即医学数字成像和通信,是医学图像和相关信息的国际标准(ISO 12052 ...

  2. Intellij IDEA创建maven项目无java文件问题

    在idea开发工具中创建工程时,点击右键没有创建包.接口.java类的提示, 如图: 解决之前的项目目录为: 针对这种情况,对idea开发工具做以下设置. 选择File->Project Str ...

  3. CHAPTER 38 Reading ‘the Book of Life’ The Human Genome Project 第38章 阅读生命之书 人体基因组计划

    CHAPTER 38 Reading ‘the Book of Life’ The Human Genome Project 第38章 阅读生命之书 人体基因组计划 Humans have about ...

  4. LAXCUS大数据操作系统3.03版本发布,欢迎使用试用

    LAXCUS大数据操作系统3.03正式发布,欢迎下载使用试用.LAXCUS大数据操作系统,集成虚拟化.大数据.数据库.容器.中间件的多集群多用户多任务全栈通用系统软件,运行.开发.维护管理为一体的平台 ...

  5. AssertionError

    (1)p1 = multiprocessing.Process(test1)p2 = multiprocessing.Process(target=test2) 错误: p1缺少target,应为(t ...

  6. cal命令详解

    基础命令学习目录首页 原文链接:https://www.yiibai.com/linux/cal.html cal命令可以用来显示公历(阳历)日历.公历是现在国际通用的历法,又称格列历,通称阳历.“阳 ...

  7. (第十周)Beta Review会议

    项目名:食物链教学工具 组名:奋斗吧兄弟 组长:黄兴 组员:李俞寰.杜桥.栾骄阳.王东涵 Beta Review会议 时间:2016.11.14   10:00——11:30.13:30——15:00 ...

  8. Percona XtraDB Cluster 5.7

    附加:相关在线文档https://www.percona.com/software/documentation 安装要求: 1.root权限2.保证开放3306.4444.4567.4568端口3.关 ...

  9. H-ui框架制作选项卡

    本案例运用H-ui框架,写了一个选项卡案例 1. html代码(固定这样写,用一个div包裹控制条tabBar和内容条tabCon) <div id="tab-index-carteg ...

  10. css3学习笔记三

    css3有些特殊的元素选择器这和jquery相似.效果图如下