Loading

简单测下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;
}
posted @ 2023-03-19 10:23  bringlu  阅读(21)  评论(0编辑  收藏  举报