简单测下C++20 vector array lambda 的常数
某天打了一下 CF,遇到了一道 https://codeforces.com/contest/1806/problem/E
这里需要卡常。
于是在 C++20(64) 下测出来了一些神奇的结果。
结果
都测了两回
| 序号 | 方法 | 时间 1(ms) | 时间 2 (ms) |
|---|---|---|---|
| 1 | 正常数组 + 正常函数 | 607 | 592 |
| 2 | vector + lambda | 1060 | 1154 |
| 3 | 正常数组 + lambda | 638 | 733 |
| 4 | array + 正常函数 | 577 | 623 |
可以简单地得出如下结论:
- vector 在卡常题中请尽可能不要使用
- lambda 函数与正常函数比有较小常数
- array 居然可以在评测机抖动的时候比正常数组还快,可以近似认为一样快
一、正常数组
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef long double ld;
#define IL inline
#define fi first
#define se second
#define mk make_pair
#define pb push_back
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()
#define dbg1(x) cout << #x << " = " << x << ", "
#define dbg2(x) cout << #x << " = " << x << endl
template<typename Tp> IL void read(Tp &x) {
x=0; int f=1; char ch=getchar();
while(!isdigit(ch)) {if(ch == '-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
x *= f;
}
int buf[42];
template<typename Tp> IL void write(Tp x) {
int p = 0;
if(x < 0) { putchar('-'); x=-x;}
if(x == 0) { putchar('0'); return;}
while(x) {
buf[++p] = x % 10;
x /= 10;
}
for(int i=p;i;i--) putchar('0' + buf[i]);
}
const int N = 100000 + 5;
const int Block_sz = 325;
const int B = 320;
int a[N], pa[N], dep[N], cnt[N], id[N];
ll ump[N][Block_sz];
vector<int> G[N];
ll GetAns(int u, int v) {
if(!u || !v) return 0;
if(u > v) swap(u, v);
if(cnt[dep[u]] <= B && ump[u][id[v]]) return ump[u][id[v]];
ll ret = GetAns(pa[u], pa[v]) + 1ll * a[u] * a[v];
if(cnt[dep[u]] <= B) ump[u][id[v]] = ret;
return ret;
}
void dfs(int u, int fa) {
dep[u] = dep[fa] + 1; id[u] = ++cnt[dep[u]];
for(int v : G[u]) {
dfs(v, u);
}
}
void solve() {
int n, q; read(n); read(q);
for(int i=1;i<=n;i++) read(a[i]);
for(int i=2;i<=n;i++) {
read(pa[i]);
G[pa[i]].pb(i);
}
dfs(1, 0);
while(q--) {
int u, v; read(u); read(v);
write(GetAns(u, v)); putchar(10);
}
}
int main() {
#ifdef LOCAL
freopen("test.in", "r", stdin);
// freopen("test.out", "w", stdout);
#endif
int T = 1;
// read(T);
while(T--) solve();
return 0;
}
二、vector + lambda 函数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef long double ld;
#define IL inline
#define fi first
#define se second
#define mk make_pair
#define pb push_back
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()
#define dbg1(x) cout << #x << " = " << x << ", "
#define dbg2(x) cout << #x << " = " << x << endl
template<typename Tp> IL void read(Tp &x) {
x=0; int f=1; char ch=getchar();
while(!isdigit(ch)) {if(ch == '-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
x *= f;
}
int buf[42];
template<typename Tp> IL void write(Tp x) {
int p = 0;
if(x < 0) { putchar('-'); x=-x;}
if(x == 0) { putchar('0'); return;}
while(x) {
buf[++p] = x % 10;
x /= 10;
}
for(int i=p;i;i--) putchar('0' + buf[i]);
}
void solve() {
int n, q; read(n); read(q);
vector<int> a(n + 1, 0), pa(n + 1, 0), dep(n + 1, 0), cnt(n + 1, 0), id(n + 1, 0);
vector<vector<int> > G(n + 1);
for(int i=1;i<=n;i++) read(a[i]);
for(int i=2;i<=n;i++) {
read(pa[i]);
G[pa[i]].pb(i);
}
const int Block_sz = sqrt(100000);
vector<vector<ll> > ump(n + 1, vector<ll>(Block_sz + 5));
function<ll(int, int)> GetAns = [&](int u, int v) -> ll {
if(!u || !v) return 0;
if(u > v) swap(u, v);
if(cnt[dep[u]] <= Block_sz && ump[u][id[v]]) return ump[u][id[v]];
ll ret = GetAns(pa[u], pa[v]) + 1ll * a[u] * a[v];
if(cnt[dep[u]] <= Block_sz) ump[u][id[v]] = ret;
return ret;
};
function<void(int, int) > dfs = [&](int u, int fa) -> void {
dep[u] = dep[fa] + 1; id[u] = ++cnt[dep[u]];
for(int v : G[u]) {
dfs(v, u);
}
};
dfs(1, 0);
while(q--) {
int u, v; read(u); read(v);
write(GetAns(u, v)); putchar(10);
}
}
int main() {
#ifdef LOCAL
freopen("test.in", "r", stdin);
// freopen("test.out", "w", stdout);
#endif
int T = 1;
// read(T);
while(T--) solve();
return 0;
}
三、正常数组 + lambda
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef long double ld;
#define IL inline
#define fi first
#define se second
#define mk make_pair
#define pb push_back
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()
#define dbg1(x) cout << #x << " = " << x << ", "
#define dbg2(x) cout << #x << " = " << x << endl
template<typename Tp> IL void read(Tp &x) {
x=0; int f=1; char ch=getchar();
while(!isdigit(ch)) {if(ch == '-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
x *= f;
}
int buf[42];
template<typename Tp> IL void write(Tp x) {
int p = 0;
if(x < 0) { putchar('-'); x=-x;}
if(x == 0) { putchar('0'); return;}
while(x) {
buf[++p] = x % 10;
x /= 10;
}
for(int i=p;i;i--) putchar('0' + buf[i]);
}
const int N = 100000 + 5;
const int Block_sz = 320;
const int B = 320;
int n, q;
int a[N], pa[N], dep[N], cnt[N], id[N];
ll ump[N][Block_sz+5];
vector<int> G[N];
void solve() {
read(n); read(q);
for(int i=1;i<=n;i++) read(a[i]);
for(int i=2;i<=n;i++) {
read(pa[i]);
G[pa[i]].pb(i);
}
function<ll(int, int)> GetAns = [&](int u, int v) -> ll {
if(!u || !v) return 0;
if(u > v) swap(u, v);
if(cnt[dep[u]] <= Block_sz && ump[u][id[v]]) return ump[u][id[v]];
ll ret = GetAns(pa[u], pa[v]) + 1ll * a[u] * a[v];
if(cnt[dep[u]] <= Block_sz) ump[u][id[v]] = ret;
return ret;
};
function<void(int, int) > dfs = [&](int u, int fa) -> void {
dep[u] = dep[fa] + 1; id[u] = ++cnt[dep[u]];
for(int v : G[u]) {
dfs(v, u);
}
};
dfs(1, 0);
while(q--) {
int u, v; read(u); read(v);
write(GetAns(u, v)); putchar(10);
}
}
int main() {
#ifdef LOCAL
freopen("test.in", "r", stdin);
// freopen("test.out", "w", stdout);
#endif
int T = 1;
// read(T);
while(T--) solve();
return 0;
}
四、array + 正常函数
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef long double ld;
#define IL inline
#define fi first
#define se second
#define mk make_pair
#define pb push_back
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()
#define dbg1(x) cout << #x << " = " << x << ", "
#define dbg2(x) cout << #x << " = " << x << endl
template<typename Tp> IL void read(Tp &x) {
x=0; int f=1; char ch=getchar();
while(!isdigit(ch)) {if(ch == '-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
x *= f;
}
int buf[42];
template<typename Tp> IL void write(Tp x) {
int p = 0;
if(x < 0) { putchar('-'); x=-x;}
if(x == 0) { putchar('0'); return;}
while(x) {
buf[++p] = x % 10;
x /= 10;
}
for(int i=p;i;i--) putchar('0' + buf[i]);
}
const int N = 100000 + 5;
const int Block_sz = 325;
const int B = 320;
array<int, N> a, pa, dep, cnt, id;
array<array<ll, Block_sz>, N> ump;
vector<int> G[N];
ll GetAns(int u, int v) {
if(!u || !v) return 0;
if(u > v) swap(u, v);
if(cnt[dep[u]] <= B && ump[u][id[v]]) return ump[u][id[v]];
ll ret = GetAns(pa[u], pa[v]) + 1ll * a[u] * a[v];
if(cnt[dep[u]] <= B) ump[u][id[v]] = ret;
return ret;
}
void dfs(int u, int fa) {
dep[u] = dep[fa] + 1; id[u] = ++cnt[dep[u]];
for(int v : G[u]) {
dfs(v, u);
}
}
void solve() {
int n, q; read(n); read(q);
for(int i=1;i<=n;i++) read(a[i]);
for(int i=2;i<=n;i++) {
read(pa[i]);
G[pa[i]].pb(i);
}
dfs(1, 0);
while(q--) {
int u, v; read(u); read(v);
write(GetAns(u, v)); putchar(10);
}
}
int main() {
#ifdef LOCAL
freopen("test.in", "r", stdin);
// freopen("test.out", "w", stdout);
#endif
int T = 1;
// read(T);
while(T--) solve();
return 0;
}
简单测下C++20 vector array lambda 的常数的更多相关文章
- C++中的数组array和vector,lambda表达式,C字符串加操作,C++中新类型数组(数组缓存),多元数组,new缓冲
使用C++风格的数组.不须要管理内存. array要注意不要溢出,由于它是栈上开辟内存. array适用于不论什么类型 #include<iostream> #include< ...
- Array.apply(null, {length: 20})和Array(20)的理解
话说今晚在学习Vue.js教程里:Render函数,这一章节是发现了一个问题,就是利用下面的这个render函数可以渲染20个重复的段落: render: function (createElemen ...
- Codeforces Global Round 6D(VECTOR<ARRAY<INT,3> >)
一个人只要存在债务关系,那么他的债务可以和这整个债务关系网中任何人连边,和他当初借出或欠下的人没有关系.只需要记录他的债务值即可. #define HAVE_STRUCT_TIMESPEC #incl ...
- 简单聊下Unicode和UTF-8
今晚听同事分享提到这个,简单总结下. ## Unicode字符集 Unicode的出现是因为ASCII等其他编码码不够用了,比如ASCII是英语为母语的人发明的,只要一个字节8位就能够表示26个英文字 ...
- 简单聊下IO复用
没图,不分析API Java中IO API的发展:Socket -> SocketChannel -> AsynchronousSocketChannelServerSocket -> ...
- Ubuntu_10.04下Hadoop-0.20.2集群配置手册
Ubuntu_10.04下Hadoop-0.20.2集群配置手册 一.软硬件环境的准备 下面的文章来自hadoopor.com,我先交待一下我自己的环境: 两台机器,每台机器上面两个虚机(vmware ...
- JQuery -> 超级简单的下拉菜单
使用jquery实现一个超级简单的下拉菜单. 效果图 最初的效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRmVlTGFuZw==/font/5a6L ...
- 简单分析下用yii2的yii\helpers\Html类和yii.js实现的post请求
yii2提供了很多帮助类,比如Html.Url.Json等,可以很方便的实现一些功能,下面简单说下这个Html.用yii2写view时时经常会用到它,今天在改写一个页面时又用到了它.它比较好用的地方就 ...
- Example017简单的下拉框
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 简单说下 Winform 的分页快速开发框架必须要实现的几个功能之一
简单说下 Winform 的分页快速开发框架必须要实现的几个功能之一 分页非为前端分页 和 后端分页,前端分页只有适用于B/S,B/S的呈现速度远远不如C/S,而C/S则没有这个问题,所以分页必然是 ...
随机推荐
- Pod进阶篇-Pod生命周期和健康探测以及startupProbe(6)
一.Pod容器探测和钩子 1.1 容器钩子:postStart和preStop postStart:容器创建成功后,运行前的任务,用于资源部署.环境准备等. preStop:在容器被终止前的任务,用于 ...
- .NET Aspire 预览版 6 发布
.NET Aspire 预览版 6 引入了一系列重大更新,主要包括 API 的重大更改.安全性和可靠性的提升.新的资源和组件.应用程序主机的更新.测试支持.模板更新.组件更新.Azure 配置包的更新 ...
- ChatGPT开源项目精选合集
大家好,我是 Java陈序员. 2023年,ChatGPT 的爆火无疑是最值得关注的事件之一,AI对话.AI绘图等工具层出不穷. 今天给大家介绍几个 ChatGPT 的开源项目! 关注微信公众号:[J ...
- 【内存优化】Oracle 的SGA与Linux的shmall和shmmax的关联
查看linux下的Oracle共享内存段 [oracle@oradb ~]$ ipcs -m ------ Shared Memory Segments -------- key shmid owne ...
- 第五章-WAF 绕过
WAF 绕过 1.WAF分类 1.1.软件 WAF 一般被安装到 Web 服务器中直接对其进行防护,能够接触到服务器上的文件,直接检测服务器上是否有不安全的文件和操作等. 常见的软件:安全狗.云盾.云 ...
- cesium教程2-加载显示地形地图
上面地形数据,是调用cesium官方的地图服务,需要先注册cesium账户,配置cesium的账户token才行 1.在线地形服务的示例代码如下 <!DOCTYPE html> <h ...
- 海康iSC综合安防平台-视频web插件调试
综合安防管理平台 视频WEB插件 1.demo_window_simple_playback.html.demo_window_simple_preview.html为简化版demo,可在此基础上开发 ...
- Java面试题:线程池内“闹情绪”的线程,怎么办?
在Java中,线程池中工作线程出现异常的时候,默认会把异常往外抛,同时这个工作线程会因为异常而销毁,我们需要自己去处理对应的异常,异常处理的方法有几种: 在传递的任务中去处理异常,对于每个提交到线程池 ...
- 一个网格合并(weld)小工具
在日常开发中会有需求合并多个Mesh网格,并且它们重合处的顶点也要合并,而并非合并成两个subMesh. 而近期刚好在学习Geomipmap的细分,需要把多个mesh块进行合并,于是写了这个脚本 (简 ...
- AIRIOT物联网低代码平台如何配置三菱PLC驱动?
三菱PLC驱动配置使用三菱Melsec协议(MC协议)从三菱PLC读取数据,仅支持以太网方式.三菱PLC都可以通过此协议访问,但是需要对PLC进行设置. AIRIOT物联网低代码平台如何配置三菱PLC ...