某天打了一下 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 的常数的更多相关文章

  1. C++中的数组array和vector,lambda表达式,C字符串加操作,C++中新类型数组(数组缓存),多元数组,new缓冲

     使用C++风格的数组.不须要管理内存. array要注意不要溢出,由于它是栈上开辟内存. array适用于不论什么类型 #include<iostream> #include< ...

  2. Array.apply(null, {length: 20})和Array(20)的理解

    话说今晚在学习Vue.js教程里:Render函数,这一章节是发现了一个问题,就是利用下面的这个render函数可以渲染20个重复的段落: render: function (createElemen ...

  3. Codeforces Global Round 6D(VECTOR<ARRAY<INT,3> >)

    一个人只要存在债务关系,那么他的债务可以和这整个债务关系网中任何人连边,和他当初借出或欠下的人没有关系.只需要记录他的债务值即可. #define HAVE_STRUCT_TIMESPEC #incl ...

  4. 简单聊下Unicode和UTF-8

    今晚听同事分享提到这个,简单总结下. ## Unicode字符集 Unicode的出现是因为ASCII等其他编码码不够用了,比如ASCII是英语为母语的人发明的,只要一个字节8位就能够表示26个英文字 ...

  5. 简单聊下IO复用

    没图,不分析API Java中IO API的发展:Socket -> SocketChannel -> AsynchronousSocketChannelServerSocket -> ...

  6. Ubuntu_10.04下Hadoop-0.20.2集群配置手册

    Ubuntu_10.04下Hadoop-0.20.2集群配置手册 一.软硬件环境的准备 下面的文章来自hadoopor.com,我先交待一下我自己的环境: 两台机器,每台机器上面两个虚机(vmware ...

  7. JQuery -&gt; 超级简单的下拉菜单

    使用jquery实现一个超级简单的下拉菜单. 效果图 最初的效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvRmVlTGFuZw==/font/5a6L ...

  8. 简单分析下用yii2的yii\helpers\Html类和yii.js实现的post请求

    yii2提供了很多帮助类,比如Html.Url.Json等,可以很方便的实现一些功能,下面简单说下这个Html.用yii2写view时时经常会用到它,今天在改写一个页面时又用到了它.它比较好用的地方就 ...

  9. Example017简单的下拉框

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. 简单说下 Winform 的分页快速开发框架必须要实现的几个功能之一

    简单说下 Winform 的分页快速开发框架必须要实现的几个功能之一 分页非为前端分页  和 后端分页,前端分页只有适用于B/S,B/S的呈现速度远远不如C/S,而C/S则没有这个问题,所以分页必然是 ...

随机推荐

  1. Unity热更学习笔记--AB包的依赖 0.98

    AB包的依赖 接上一小结. 在这里我们新建一个红色材质球,赋值给Cube预制体.此时不对材质球进行AB包分类,再次进行打包.运行脚本,发现红色cube成功的从AB包中加载出来.尽管我们没有将cube所 ...

  2. 【Python Web】flask视频流

    这篇文档,完全借鉴miguelgrinberg的博客. https://blog.miguelgrinberg.com/post/flask-video-streaming-revisited 想看具 ...

  3. tomcat(3)- tomcat部署zrlog

    目录 1. Tomcat单独部署 2. nginx+tomcat部署 1. Tomcat单独部署 部署场景为: 客户端:192.168.20.1 tomcat:主机名:tomcat01,地址:192. ...

  4. 应急响应web1

    应急响应的过程 目的:分析攻击时间.攻击操作.攻击结果.安全修复等并给出合理的解决方案. 保护阶段:直接断网,保护现场,看是否能够恢复数据: 分析阶段:对入侵过程进行分析,常见的方法为指纹库搜索.日志 ...

  5. LLM实战:LLM微调加速神器-Unsloth + LLama3

    1. 背景 五一结束后,本qiang~又投入了LLM的技术海洋中,本期将给大家带来LLM微调神器:Unsloth. 正如Unsloth官方的对外宣贯:Easily finetune & tra ...

  6. docker之docker-compose

    docker-compose就是个二进制的工具,它可以单机编排,批量管理多个容器 [root@mcwk8s01 harbor]# file /usr/local/bin/docker-compose ...

  7. 【题解】P2627 [USACO11OPEN] Mowing the Lawn G

    [题解]P2627 [USACO11OPEN] Mowing the Lawn G 题目跳转 数据量比较大,暴力肯定是不行的.只能考虑用动态规划的方式来做. 这道题有许多dp设计的思路,这里提供两个: ...

  8. uniapp uni-number-box组件 步长为1,还能输入小数思路分享

    正常情况,输入了步长为1,是无法在输入小数的.需求是要能输入一位小数,但如果直接步长设为0.1,又不能按1这样递增,输入数量上用起来肯定很麻烦. 于是我就想了一个折中方法,步长设为:1.01,然后值改 ...

  9. 【Sqlserver】查看所有数据库的大小 创建日期 名称 版本级别 状态

    EXEC  sp_helpdb

  10. WPF 中使用附加属性解决 PasswordBox 的数据绑定问题

    1.前言 在 WPF 开发中 View 中的数据展示我们常通过 Binding 进行绑定.但是,使用 Binding 有一个前提:绑定的目标只能是依赖属性. 而 PasswordBox 控件中的 Pa ...