某天打了一下 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. 浅析mvvm模式和mvc模式的区别和联系

    三层架构与MVC模式 三层架构 三层架构是一种以实现"高内聚,底耦合"为目标,的代码架构方法,它将整个业务分为,表示层,业务层,数据访问层(Dao层). MVC模式 MVC模式是一 ...

  2. Nats集群部署

    环境: 3台机器采用同样的目录名字和文件名称 服务器 192.168.10.30 192.168.10.31 192.168.10.32 nats版本2.9.15 配置文件 # 192.168.10. ...

  3. .NET Aspire 预览版 6 发布

    .NET Aspire 预览版 6 引入了一系列重大更新,主要包括 API 的重大更改.安全性和可靠性的提升.新的资源和组件.应用程序主机的更新.测试支持.模板更新.组件更新.Azure 配置包的更新 ...

  4. SpringMVC学习五(resultful风格/异常处理/注解)

    resultful风格 异常处理 1.Restfule风格 Restfule风格是一种软件架构风格,而不是标准,只是提供了一种设计原则和约束条件.主要适用于客户端和服务器端交互的软件.是基于http协 ...

  5. Linux中的touch命令

    Linux中一个文件有3种时间属性,分别是mtime,ctime,atime: modification time (mtime) 当该文件的『内容数据』变更时,就会升级这个时间!内容数据指的是文件的 ...

  6. python教程6.4-json序列化

    序列化:dumps,编码,将python类型转成json对象 反序列化:loads,解码,将json对象转成python对象 pickle 模块提供了四个功能:dumps.loads.dump.loa ...

  7. C语言:卖鸭子问题---递归法实现

    1.一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只.这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子? 代码: #include<st ...

  8. 一:nacos 的安装与启动方式

    一: nacos 的下载与安装 1,下载 到 github下载  nacos-server-1.2.0.zip  文件   :https://github.com/alibaba/nacos/rele ...

  9. 你可能不知道的秘密——String s=new String(“abc”)到底创建了几个对象?

    String s=new String("abc")创建了几个对象? ​   在探讨上述问题结论之前,我们需要了解常量池这个概念. 常量池 ​   由于字符串在Java中被大量使用 ...

  10. Gitea 代码仓库平台

    引言 Gitea 是一个自己托管的 Git 服务程序.他和 GitHub,Bitbucket or Gitlab 等比较类似.它是从 Gogs 发展而来,不过它已经 Fork 并且命名为 Gitea. ...