指针

lower_boundupper_bound运用时的返回值是指针,可以用 auto 来存储(现在比赛基本都 c++14 了,放心用)。有时常见的解决方法为‘减去数组’,如:

int a[N], n, x;
int k = lower_bound(a + 1, a + n + 1, x) - a;

此外,还有很多 STL 函数的返回值是迭代器,与指针区别不大,可以视作指针。
但结构体数组或是一些 STL (如 set) 返回的好像不是很好操作,还是用 auto 存。以下为一些运用方法:

struct a{
	int id;
	bool f;
};
set<a> st;
//假设 set 中插入了很多值
auto k = upper_bound((a){1, 1});
a x = *k;

int y = k -> id; //等同于 y = x.id
bool z = k -> f; //等同于 z = x.f
if(k != st.end()){ //可以直接比较
	k --; //将指针前移一位
}

重载运算符

常运用于结构体函数中,改变重载运算符号的作用。
一般形式为:
* operator *('const' * &x)'const'{}
第一个 * 为函数返回类型;第二个 * 为重载的运算符号;第三个 * 为读取的 \(x\) 的类型。
两个 const 都是可有可无的,但都有作用。第一个 const 可令 \(x\) 的值不会被改变;第二个 const 可令原有的进行运算的值不会被改变。

struct node{
	int id;
	bool f;
	
	inline bool operator <(const node &x)const{
	//返回类型为 bool, 重载 <,读入 x 类型为 node
	//使 x 不会被更改,使 id、 f 不会被更改
	//id, f 表示原结构体中的 id, f
	//x.id, x.f 表示 x 中的 id, f
		if(f ^ x.f) return f < x.f;
		return id < x.id;
	} //此结构体中的 < 以 f 为第一关键字,id 为第二关键字进行比较
};
set<node> st;
//此 set 中的 < 因 node 被重载而重载

曼哈顿距离和切比雪夫距离

曼哈顿距离与切比雪夫距离的互化

曼哈顿距离

对于两个点 \((x_1, y_1), (x_2, y_2)\) ,他们的曼哈顿距离为 \(|x_1-x_2|+|y_1-y_2|\)

切比雪夫距离

对于两个点 \((x_1, y_1), (x_2, y_2)\) ,他们的切比雪夫距离为 \(max(|x_1-x_2|,|y_1-y_2|)\)

曼哈顿距离和切比雪夫距离的互化

将式子写成类似的形式:

  • 曼哈顿距离:\(max(x_1-x_2+y_1-y_2,\ x_1-x_2-y_1+y_2,\ -x_1+x_2+y_1-y_2,\ -x_1+x_2,-y_1+y_2)\)
  • 切比雪夫距离:\(max(x_1-x_2,\ -x_1+x_2,\ y_1-y_2,\ -y_1+y_2)\)

简单推导一下可以得出:

  • 曼哈顿距离转切比雪夫距离:将每个点 \((x, y)\) 转化为 \((x+y, x-y)\)
  • 切比雪夫距离转曼哈顿距离:将每个点 \((x, y)\) 转化为 \((\dfrac{x+y}{2}, \dfrac{x-y}{2})\)

极角排序

需要用到 atan2 函数
atan2(y,x) 返回浮点数,表示点 \((x, y)\) 与原点连线的 tan 值,值域为 \([-\pi,\pi]\)
用于极角排序时常是这样:

struct node{
	int x, y;
};
inline bool cmp(node a, node b){ //此处排序为以默认原点为一端
	double sum = atan2(a.y, a.x) - atan2(b.y, b.x);
	if(!sum) return a.x < b.x;
	return sum < 0;
}

范德蒙德卷积

\[\sum_{i = 0}^{k}C_{n}^{i}C_{m}^{k-i}=C_{n+m}^{k} \]

用二项式定理可证

关于上下取整

  • \(a\le\lfloor\frac{b}{c}\rfloor \rightarrow a\le\frac{b}{c}\)
  • \(\frac{b}{c}\lt a \rightarrow\lfloor\frac{b}{c}\rfloor\lt a\)
  • \(\lfloor\frac{a}{b}\rfloor+\lceil\frac{bx-a}{b}\rceil=x\)

区间 mex

在权值线段树上存 \(x\) 最后一次的出现位置
对于区间 \([l,r]\) ,在第 \(r\) 棵线段树上查找最小的值小于 \(l\) 的值即可
可以用可持久化在线优化到 log

Dfn序求 Lca

若点 \(x\) 的 Dfn序大于 \(y\) ,则将 \(x\) 一直往父亲跳直至 Dfn序小于等于 \(y\),再把 \(y\) 往上跳至同一位置即可
关于正确性,画图很好理解

图上查询两点是否在同一边双内

建出随意一颗生成树,对于所有的原边,在生成树上进行链覆盖
若两点间所有边覆盖次数都 \(\le 2\) ,则两点间必有两条及以上的不同路径,故在同一边双内

posted @ 2024-04-10 21:42  Biuld  阅读(11)  评论(0编辑  收藏  举报