首页 > 其他分享 >闲话 22.9.26

闲话 22.9.26

时间:2022-09-26 06:55:33浏览次数:97  
标签:26 val int 闲话 itl pos split 区间 22.9

闲话

调全体T4
六点改出来了,但大样例不认为我改出来了
于是又花了两个小时修改不存在的错误

最近在做这题
[JRKSJ R4] risrqnis
想做主要是因为上琴糖
但是做着做着发现很神 而且我不会
请大家都来切一下(

所以写了珂朵莉树。
主要是因为复杂度的证明
这题一样神奇

命は綺麗なわけじゃない

美しい人生なんてない

呼吸が上手く出来ないのは

生きてる証拠だ

关于颜色段均摊

又名珂朵莉树。

总而言之是一种通过均摊证出来的正确算法。特用于维护类似于区间改成一个值(或可以快速确定值)的操作。
具体有以下两种:

  1. 四种及以下操作,其中一个是 \([l,r]\) 赋值为 \(v\)。保证数据完全随机。
  2. 操作是 \([l,r]\) 赋值为 \(v\)。

先说1的做法。我们使用一个 set,其中每个元素记录 \(v\) 相同的区间 \([l, r]\)。set 的小于就按 \(l\) 小于重载,毕竟你得保证这里面的区间并是 \([1,n]\) 并且没有交。

#define IT set<node>::iterator
struct node {
	mutable int l, r, val;
	node(int lf, int rt, int v) : l(lf), r(rt), val(v) {}
	bool operator < (const node & b) const 
	{ return l < b.l; }
};
set<node> s;

就这么写一下。set 的元素操作一般带一个 const 修饰,为了进行接下来的操作我们需要给元素上一个 mutable 保证能改值。记得把迭代器定义成好写的名字,因为一会儿得用很多次。

珂朵莉树的核心操作是分裂区间,即 \(split(pos)\) 函数。它会把 \(pos\) 所在区间 \([l,r]\) 分裂成 \([l,pos-1]\) 和 \([pos,r]\) 然后返回后一段。直接在 set 里查一下再处理就行。

inline IT split(int pos) {
	IT it = s.lower_bound(node(pos, 0, 0));
	if (it != s.end() and it->l == pos) return it;
	it--; if (it->r < pos) return s.end();
	int l = it->l, r = it->r, val = it->val;
	s.erase(it);
	s.insert(node(l,pos-1,val));
	return s.insert(node(pos,r,val)).first; // insert返回一个 <iterator,bool> 的 pair
}

然后有了分裂就得有合并,即区间赋值函数 \(assign(l,r,v)\)。@brief This does what you think it does.

inline void assign_val(int l, int r, ll val) {
	IT itr = split(r+1);
	IT itl = split(l);
	s.erase(itl, itr);
	s.insert(node(l,r,val));
}

记得先 split 右边再 split 左边。因为左边 split 出来的迭代器可能会被右边 erase 掉,它可能指向一个非法地址。

然后有了区间赋值操作,剩下的东西就直接暴力就好。拿板子题CF896C说。show you the code:
区间加:

inline void add(int l, int r, ll val) {
	IT itr = split(r+1);
	IT itl = split(l);
	while (itl != itr) itl->val += val, itl++;
}

区间 \(k\) 小:

struct rnks {
	int num, cnt;
	bool operator < (const rnks & b) const
		{ return num < b.num; }
	rnks(int nm, int ct) : num(nm), cnt(ct) {}
};

inline ll rnk(int l, int r, ll k) {
	vector <rnks> vp;
	IT itr = split(r+1);
	IT itl = split(l);
	vp.clear();
	while(itl != itr) {
		vp.push_back(rnks(itl->val, itl->r - itl->l + 1));
		itl++;
	} sort(vp.begin(), vp.end()); 
	int pos;
	for (pos = 0; pos < vp.size(); ++pos) {
		if (k > vp[pos].cnt) k -= vp[pos].cnt;
		else break;
	} return vp[pos].num;
}

区间 \(p\) 次方和:

inline ll sum(int l, int r, int pw, int p) {
	IT itr = split(r+1);
	IT itl = split(l);
	ll ret = 0;
	while (itl != itr) {
		ret = (ret + (itl->r - itl->l + 1) * qp(itl->val, pw, p)) % p, itl++;
	} return ret;
}

然后证一下复杂度:

引理:在长度为1的区间内随机撒两个点,它们的间距为 \(\frac 13\)。
证:考虑积分。我们发现这个玩意的答案是

\[\iint_D |y - x| dxdy \]

其中 \(D\) 为 \(x = 0, x = 1, y = 0, y = 1\) 围成的范围。然后进行一些初等的积分。

\[\begin{aligned} &\iint_D |y - x| dxdy \\ = &\ \int_0^1 dy \int_0^1 |y - x| dx \\ = &\ 2\int_0^1 dy \int_0^y (y - x) dx \\ = &\ 2\int_0^1 dy (\int_0^y ydx - \int_0^y xdx) \\ = &\ 2\int_0^1 dy (y^2 - \frac 12 y^2) \\ = &\ \int_0^1 y^2 dy \\ = &\ \frac 13 \end{aligned}\]

因此由于数据随机,区间长度大致是 \(\frac n3\) 的(实际上期望是 \(\frac {n-1} 3\) 但需要一些离散和式的操作 麻烦不写)

定理:当有 \(\frac 14\) 的操作为区间赋值时,珂朵莉树内维护的区间数量的确界为 \(\Theta(\log n)\)。
不证,因为不会。

lxl说当有 \(\frac 13\) 的操作为赋值时有上界 \(O(\log\log n)\)。
也不会证。

例题:Willem, Chtholly and Seniorious

对于2情况,我们发现每个区间扔进珂朵莉树时只会增加 \(O(1)\) 个区间。每个区间花费 \(O(\log n)\) 的复杂度维护(split + assign),摊完复杂度是 \(O(n \log n)\) 的。因此直接维护就行,这里的复杂度一般不是瓶颈。

例题:[YER 2021] TEST_152

eazy round 真就 eazy 题 希望大家都能去切一下水题(
直接用珂朵莉树维护颜色段就行,每次加入删除连续段时对应地修改贡献,这部分的总复杂度是 \(O(n \log n)\) 的。

标签:26,val,int,闲话,itl,pos,split,区间,22.9
From: https://www.cnblogs.com/joke3579/p/chitchat220926.html

相关文章

  • 闲话?2020.9.25
    //闲话的真正形态是什么?我至今为止的可以称之为闲话的博都有在“雕琢”(用输入法打you第一个字是幼,不愧是我。),但这是否违背了闲话的初衷?一篇闲话会用VScode写上一两......
  • 【闲话】2022.09.25
    考试++虽然我个人习惯是++i。hereRSY大佬大家快去关注\(\texttt{_RSY_}\)大佬!顺便记得不要像我一样写题解的时候老爱加空格。失踪人口回归L回来了(说起来L......
  • Value error: 'ascii' codec can't decode byte 0xe6 in position 26: ordinal not in
    原因:工作空间中有中文编码问题,导致的运行ros异常解决办法:1、解决urdf生成异常问题urdf文件中不允许有中文,所有当输入中文的时候容易出问题,解决方案:①在根目录下:/opt/ro......
  • 2022-2023-1 20221326《计算机基础与程序设计》第四周学习总结
    班级链接:https://edu.cnblogs.com/campus/besti/2022-2023-1-CFAP作业要求:https://www.cnblogs.com/rocedu/p/9577842.html#WEEK04作业目标:门电路组合电路,逻辑电路冯诺依......
  • 2022.9.24 总结
    B\(A\)\(B\)轮流行动,\(A\)需要拿走若干个数(不可不拿),\(B\)可以拿走一个数。\(A\)拿走的数和要最大,\(B\)则希望\(A\)拿走的数和最小。问\(A\)能拿走多少数的和......
  • 9.24 闲话
    发现大家都喜欢在闲话里放歌词。那我也放一个珍藏了多年的好了。然而发现自己只有歌词翻译和罗马音。所以还是放个四重罪孽好了。四重罪孽我经历一场革变在......
  • 闲话 22.9.24
    闲话一天两场模拟赛全在模拟抱泠我的体活听eafoo说明天早上似乎跑操整个什么尸气大比拼彳亍都在放涩图但是我没涩图我有饭的图于是放一张小宇宙日和《关于......
  • sqlalchemy.exc.OperationalError: (MySQLdb._exceptions.OperationalError) (2026, '
    sqlalchemy.exc.OperationalError:(MySQLdb._exceptions.OperationalError)(2026,'SSLconnectionerror:unknownerrornumber')问题:使用sqlalchemy查询mysql数据时......
  • SOJ1626 方珍 题解
    传送门题意给定一个\(n×n\)的方阵,其中第\(i\)行为\(A_{i,1},A_{i,2},...,A_{i,n}\)。对于\(A_i\)的所有区间,设\(f_i\)为其中第\(k_i\)大的\(mex\)值。给......
  • 力扣-226-翻转二叉树/剑指Offer-27-二叉树的镜像
    直达链接直观的想法:我可以遍历并重建,但也很明显效率低下,可能达到O(N2),但或许可能拿来当作练习,检查自己遍历/重建二叉树的基本功不过现在先想想有没有效率更高的解法,我觉......