2025.3.27 鲜花

news/2025/4/1 17:21:06/文章来源:https://www.cnblogs.com/xrlong/p/18794777

如何优雅的使用 stl

啥背景,杀乌鸡 ``` Viumbe vyote vya mungu wetu na mfalme wetu Pazeni sauti ili nasi mwimbe Pazeni sauti ili nasi mwimbe Pazeni sauti Pazeni sauti Viumbe vyote vya mungu wetu na mfalme wetu Pazeni sauti ili nasi mwimbe Pazeni sauti ili nasi mwimbe Pazeni sauti ili nasi mwimbe Viumbe vyote vya mungu wetu na mfalme wetu Pazeni sauti ili nasi mwimbe Pazeni sauti ili nasi mwimbe Pazeni sauti ili nasi mwimbe Pazeni sauti Pazeni sauti Pazeni sauti ili nasi mwimbe Pazeni Pazeni Pazeni PazeniPazeni Pazeni Viumbe vyote vya mungu wetu na mfalme wetu Pazeni sauti ili nasi mwimbe Pazeni sauti ili nasi mwimbe Pazeni sauti ili nasi mwimbe Pazeni sauti Pazeni sauti Pazeni sauti ili nasi mwimbePazeni sauti Pazeni sauti Pazeni sauti Pazeni sauti ```

众所周知的,priority_queue 可以通过一下方式传 lambda 比较函数。

auto Cmp = [](int a, int b){return a > b;};
priority_queue<int, vector<int>, decltype(Cmp)> que(Cmp);

有没有不定义 Cmp 的办法呢?

我们用

#include <cxxabi.h>
cout << abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, nullptr) << endl;

输出一下 decltype(Cmp) 到底是什么类型,它其实是一个 lambda 的类型,根本没法输出。

我们翻找 priority_queue 的原理,容易发现其调用了一个构造函数

priority_queue(const _Compare& __x, _Sequence&& __s = _Sequence()): c(std::move(__s)), comp(__x){ std::make_heap(c.begin(), c.end(), comp); }

所以它内置了一个比较对象,而我们传入的第三个参就是其类型,我们可以通过构造函数来初始化这个对象。

于是我们用 function 替换掉 decltype 即可:

priority_queue<int, vector<int>, function<bool(int, int)>> que([](int a, int b){return a > b;});

事实上,我们可以自己写一个类似的东西,形如:

template <class T>
class A{T f;A() = default;A(auto k) : f(k){}
};

注意在 C++20 以前 lambda/function 是不能作为值传入 template 的。

当然你也可以用昨天鲜花的内容转成函数指针来传入。


众所周知,可以用 #define protected private 访问 queuestack 的底层结构,类似:

#define protected public
#include <stack>
#include <queue>
#undef protectedqueue<int> que;
for(int i = 1; i <= 10; ++i)que.emplace(i);
for(int i = 9; ~i; --i)cout << que.c[i] << ' ';

这个其实可以扩展。

对于 priority_queue,我们类似做

#define protected public
#include <stack>
#include <queue>
#undef protectedpriority_queue<int> que;
for(int i = 1; i <= 10; ++i)que.emplace(i);
for(int i = 9; ~i; --i)cout << que.c[i] << ' ';

发现并不是有序的。

这是因为其内部是通过 make_heap 实现的,详细了解可以直接搜,这里说一下如何让他有序。

sort_heap(que.c.begin(), que.c.end(), less<int>())less<int>()que 的比较函数,注意这里是倒序的。

想还原可以用 make_heap(que.c.begin(), que.c.end(), less<int>())

对于 bitset,我们也可以直接访问,形如:

#define private public
#include <bitset>
#undef privatebitset<10000> s;
s._M_w[i];

默认是用 long 压的,一般是 \(64\),注意就是这个是 private,并且是 ._M_w[]

这样其实就解决了必须手写 bitset 的一个方面。

给出 P11831 [省选联考 2025] 追忆 的代码。甚至比我手写快

Code
/* Local File
in_out/in.in
in_out/out.out
*/
#define private public
#include <bitset>
#undef private
#include <bits/stdc++.h>
using namespace std;
using llt = long long;
using ull = unsigned long long;
using llf = long double;
#define endl '\n'const int N = 1e5 + 3, W = 64, D = N / W + 1, B = 600, S = N / B + 3;
int n, m, q, va[N], vb[N], pa[N], pb[N];bitset<N> sn[N], ca[S], cb[S];
int bln, id[N], bl[N], br[N];struct Gph{vector<int> to[N];void Add(int u, int v){to[u].emplace_back(v);}void ADD(int u, int v){Add(u, v), Add(v, u);}void Clr(){for(int i = 1; i <= n; ++i)to[i].clear();}
#define For_to(u, v, g) for(auto v : g.to[u])
} g, rg;int rd[N];
void Solve(){cin >> n >> m >> q;for(int i = 1; i <= m; ++i){int u, v; cin >> u >> v;g.Add(u, v), ++rd[u], rg.Add(v, u);}for(int i = 1; i <= n; ++i)cin >> va[i], pa[va[i]] = i;for(int i = 1; i <= n; ++i)cin >> vb[i], pb[vb[i]] = i;queue<int> que;for(int i = 1; i <= n; ++i) if(!rd[i])que.emplace(i);while(!que.empty()){int u = que.front(); que.pop();sn[u][u] = 1;For_to(u, v, g) sn[u] |= sn[v];For_to(u, v, rg)if(!--rd[v]) que.emplace(v);}bln = 0;for(int l = 1; l <= n; l += B){++bln;for(int j = bl[bln] = l, r = br[bln] = min(l + B - 1, n); j <= r; ++j)ca[bln][pa[j]] = 1, cb[bln][pb[j]] = 1, id[j] = bln;}for(int i = bln - 1; i; --i)ca[i] |= ca[i + 1], cb[i] |= cb[i + 1];for(int tst = 1; tst <= q; ++tst){int op; cin >> op;if(op == 1){int x, y; cin >> x >> y;int ix = id[va[x]], iy = id[va[y]];swap(va[x], va[y]), pa[va[x]] = x, pa[va[y]] = y;for(int i = 1; i <= ix; ++i) ca[i][x] = 0;for(int i = 1; i <= iy; ++i) ca[i][x] = 1;for(int i = 1; i <= iy; ++i) ca[i][y] = 0;for(int i = 1; i <= ix; ++i) ca[i][y] = 1;}else if(op == 2){int x, y; cin >> x >> y;int ix = id[vb[x]], iy = id[vb[y]];swap(vb[x], vb[y]), pb[vb[x]] = x, pb[vb[y]] = y;for(int i = 1; i <= ix; ++i) cb[i][x] = 0;for(int i = 1; i <= iy; ++i) cb[i][x] = 1;for(int i = 1; i <= iy; ++i) cb[i][y] = 0;for(int i = 1; i <= ix; ++i) cb[i][y] = 1;}else{int u, l, r; cin >> u >> l >> r;int il = id[l], ir = id[r];bitset<N> k(ca[il] ^ ca[ir]);for(int i = bl[ir]; i <= r; ++i) k[pa[i]] = 1;for(int i = bl[il]; i < l; ++i) k[pa[i]] = 0;k &= sn[u];int p = 0;for(int i = 0; i < D; ++i)while(p < bln && (cb[p + 1]._M_w[i] & k._M_w[i])) ++p;if(!p) cout << 0 << endl;elsefor(int i = br[p]; i >= bl[p]; --i){int p = pb[i];if(k[p]){cout << i << endl;break;}}}}
}void Clear(){memset(sn, 0, sizeof sn);memset(ca, 0, sizeof ca);memset(cb, 0, sizeof cb);g.Clr(), rg.Clr();
}int main(){ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);int c, t; cin >> c >> t;while(t--) Solve(), Clear();
}

众所周知,在 tr2/dynamic_bitset 头文件中有一个 dynamic_bitset,其支持动态 resize

具体可以看 dynamic_bitset。

但是众所不周知,其 is_subset_of (话说这个 subset 竟然是后缀)写挂了……

所以你直接用 is_subset_of 会 CE。

5k 曾给出过:

#define is_proper_subset_of is_subset_of(const dynamic_bitset& __b)\{ return this->_M_is_subset_of(__b); }\bool qwq

我们分析一下原因。

翻找源码:

bool _M_is_subset_of(const __dynamic_bitset_base& __b) noexcept{if (__b._M_w.size() == this->_M_w.size()){for (size_t __i = 0; __i < this->_M_w.size(); ++__i)if (this->_M_w[__i] != (this->_M_w[__i] | __b._M_w[__i]))return false;return true;}else return false;
}bool is_subset_of(const dynamic_bitset& __b) const{ return this->_M_is_subset_of(__b); }

容易发现其问题:在 bool _M_is_subset_of(const __dynamic_bitset_base& __b) 后少了一个 const

写源代码不编译的人这辈子有了。

但是我们不太能直接加上一个 const,于是我们曲线救国,把 is_proper_subset_of define 成一个新的 is_subset_of 即可。

这样就不能用 is_proper_subset_of 了(当然也不能用 qwq 做变量名),但事实上是 is_proper_subset_of 的源码更绝望,其有好多错特别不好改,还是用 is_subset_of && != 替代吧。

其实要是只是想用的话有更简单的方式,我们发现 is_subset_of 本质上就是调用了一个 _M_is_subset_of,并且 dynamic_bitset__dynamic_bitset_base 之间可直接转换,所以如下即可:

#define private public
#include <tr2/dynamic_bitset>
#undef privatetr2::dynamic_bitset<> a, b;
a._M_is_subset_of(b);
P




本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/906523.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

读DAMA数据管理知识体系指南32参考数据和主数据概念(下)

读DAMA数据管理知识体系指南32参考数据和主数据概念(下)1. 主数据 1.1. 主数据是有关业务实体(如雇员、客户、产品、金融结构、资产和位置等)的数据,这些实体为业务交易和分析提供了语境信息 1.2. 实体是客观世界的对象(人、组织、地方或事物等)​ 1.3. 实体被实体、实例…

Springboot3+Vue3实现JWT登录鉴权

做鉴权原因: 管理系统的数据是敏感的,隐私的,每个角色的权限是不同的,必须在数据的增删改查操作时候对访问的用户进行权限验证 JWT(Json Web Token) 用于在网络应用间安全的传递消息。它以紧凑且自包含的方式,通过JSON对象在各方之间传递经过验证的信息。JWT通常由三部分…

搜维尔科技:SenseGlove触觉反馈手套-自动化和培训的突破

触觉力反馈技术领导者SenseGlove和机器人操控创新者Aeon宣布推出HEART项目。此次合作将虚拟现实 、力反馈触觉手套(SenseGlove)和机器人系统(Aeon)集成在一起,以实现直观控制和实时力反馈,使机器人训练更加方便和有效。 自动化和培训的突破 由于产品需求不断变化以及机器…

搜维尔科技:Haption通用遥控控制器,可轻松集成到工业机器人控制中

TeleRobotics EXtender (TREX) 是一个专为力反馈远程操作而设计的框架。它为操作员必须在危险、具有挑战性或受限的环境中操作的情况提供了一种创新的解决方案,使他们能够在不暴露自己风险的情况下执行任务。借助 TREX,操作员可以手动控制远程机器人,具有很高的灵活性和精确…

Elasticsearch 的搜索功能

Elasticsearch 的搜索功能建议阅读顺序:Elasticsearch 入门 Elasticsearch 搜索(本文)1. 介绍 使用 Elasticsearch 最终目的是为了实现搜索功能,现在先将文档添加到索引中,接下来完成搜索的方法。 查询的分类:叶子查询:叶查询子句在特定字段中查找特定值,例如 match、t…

20242213 实验二《Python程序设计》实验报告

20242213 2024-2025-2 《Python程序设计》实验2报告 课程:《Python程序设计》 班级: 2422 姓名: 刘宗林 学号:20242213 实验教师:王志强 实验日期:2025年3月26日 必修/选修: 公选课 1.实验内容设计并编写一个计算器程序,实现基本运算功能;功能包括加、减、乘、除、取余…

《实战Java高并发程序设计(第3版)》 | PDF免费下载

《实战Java高并发程序设计(第3版)》主要介绍基于Java的并行程序设计基础、思路、方法和实战。第一,立足于并行程序基础,详细介绍Java并行程序设计的基本方法。第二,进一步详细介绍JDK对并行程序的强大支持,帮助读者快速、稳健地进行并行程序开发。第三,详细讨论“锁”的…

《DeepSeek原理与项目实战》 | PDF免费下载

DeepSeek 是一种基于 Transformer 架构的生成式 AI(Artificial Intelligence)大模型,融合了MoE 架构、混合精度训练、分布式优化等先进技术,具备强大的文本生成、多模态处理和任务定制化能力。本书系统性地介绍了开源大模型 DeepSeek-V3 的核心技术及其在实际开发中的深度应…

实现极限网关(INFINI Gateway)配置动态加载

还在停机更新 Gateway 配置,OUT 了。 今天和大家分享一个 Gateway 的功能:动态加载配置(也称热更新或热加载)。 这个功能可以在 Gateway 不停机的情况下更新配置并使之生效。 配置样例如下: path.data: data path.logs: logconfigs:auto_reload: true # set true to auto …

ubuntu20.04安装Synergy

问题 最近在Ubuntu20.04上安装新版本的Synergy遇到一些问题,Synergy最后一个支持ubuntu20.04的版本是v3.1.3-beta,下面是下载地址: https://symless.com/synergy/download/other 在安装的时候遇到下面的问题:提示依赖libssl1,然后尝试安装下面的软件包: sudo apt install…

Netty源码—7.ByteBuf原理二

大纲 9.Netty的内存规格 10.缓存数据结构 11.命中缓存的分配流程 12.Netty里有关内存分配的重要概念 13.Page级别的内存分配 14.SubPage级别的内存分配 15.ByteBuf的回收9.Netty的内存规格 (1)4种内存规格 (2)内存申请单位(1)4种内存规格 一.tiny:表示从0到512字节之间的内存大…

一文速通Python并行计算:03 Python多线程编程-多线程同步(上)—基于互斥锁、递归锁和信号量

在 Python 多线程编程中,线程同步是确保多个线程安全访问共享资源的关键技术。本篇文章介绍了互斥锁(Lock)、递归锁(RLock) 和 信号量(Semaphore) 的概念与应用。互斥锁用于防止多个线程同时修改数据,递归锁适用于嵌套锁定场景,而信号量则限制同时访问资源的线程数。一…