2022.10.12 闲话

i want to make a public contest

看了一下 cppreference 的 dependent nameODR 规则ADL,深感 C++ 之牛逼啊 .

选两个比较高级的绝世好题:

  • 给定一棵有根树,动态加点,支持换根,实时查询重链剖分的链数(多个重儿子取编号最小) — fhqtreap
  • 给你一个二分图,请求出它的七元环数量 — dottle(这个好像骗过 joke3579).

如何出一道诈骗题呢?

Calc

给一个正整数 n,求

j=2n(j1)!+1j(j1)!j

1n1012 .

Koishi Loves Construction

给一个 n,要求:

  • Task 1:试判断能否构造并构造一个长度为 n1n 的排列,满足其 n 个前缀和在模 n 的意义下互不相同 .
  • Task 2:试判断能否构造并构造一个长度为 n1n 的排列,满足其 n 个前缀积在模 n 的意义下互不相同 .

如果能构造,构造一组方案 .

1n105 .

lambda 表达式实现递归的几种方案 (C++)

为什么 Python 的 lambda 表达式能直接使用递归啊?

以下 [&][=][] 不做区分(随便用 hhh).

以下的实例用一个简单递归函数演示

int f(int x){return x < 1 ? 0 : f(x-1) + 1;}

1. 使用 std :: function 包装

就是用 std :: function 包装后它就不是匿名的了,后面该咋写咋写就完了 .

类似于 C# 的

Func<int, int> f = null;
f = x => x < 1 ? 0 : f(x-1) + 1;

第一句就是先把它放着(声明)然后再用,当然这个做法在 C# 是有一定缺陷的(因为 C# 特性),但是在 C++ 里没有 .

一份实现:

auto f = [](int n)
{
	std :: function<int(int)> _;
	_ = [&](int n){return n < 1 ? 0 : 1 + _(n-1);}; 
	return _(n);
};

好像后面的做法都要 since C++14 .

2. 将自身作为参数传入

这个是最常用且最简单的了 .

不多说,直接放代码:

auto f = [](auto&& self, int x){return x < 1 ? 0 : self(self, x-1) + 1;};

传的时候要传一下 self,别的就没有什么太大的缺点了 .

3. 使用 Generic Lambda 代替方法 2 中传参

这个是最方便的了 .

std :: function<int(int)> f = [&f](int n){return n < 1 ? 0 : f(n-1) + 1;};

这里不能用 auto,因为这里的类型相当于递归了,auto 的话编译器推不出来类型 .

其实 Generic Lambda 就相当于带 template 的 lambda 表达式 .

4. 使用 Y Combinator

具体需要一些 λ 演算的知识,可以去 Wikipedia 看一下 Lambda Calculus,α-equivalentβ-reductionη-conversion 等 .

我们知道 Y 组合子(Y Combinator)是不动点组合子的一种,因为 Y 组合子相比其他不动点组合子非常容易实现所以采用 Y 组合子 .

Y 组合子:λf.(λx.f(x x))(λx.f(x x)) .

翻译成 C++(下面是一个 std :: function<int(int)> 版本的):

auto y = [](auto f)
{
	return [&](auto _){return _(_);}([&](const auto& rec) -> std :: function<int(int)>
	{
		return f([&](int arg){return rec(rec)(arg);});
	});
};

使用只需要传入一个原函数的高阶函数即可:

auto inr = [](auto f){return [&](int n){return n < 1 ? 0 : f(n-1) + 1;};};
printf("%d\n", y(inr)(114514)); // 别爆栈了 /hsh

posted @   yspm  阅读(84)  评论(3编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
😅​
点击右上角即可分享
微信分享提示