关于卡常

关于卡常

快读

普通快读

众所周知,字符串输入输出比数字快,于是就有了以下快读

namespace Q{
    il int rd(){
        ri int x=0,f=1;ri char c=getchar();
        while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
        while(c>='0'&&c<='9') x=x*10+(c^48),c=getchar();
        return x*f;
    }
    il void wt(int x){
        if(x<0) x=-x,putchar('-');
        if(x>=10) wt(x/10);
        return putchar(x%10+48),void();
    }
} using namespace Q;

快快读~

一般情况下,上面的快读就够用了
但是如果只差一点就可以卡进去的话,可以考虑一下快快读(注意空间,可能会MLE

namespace Q{
    cs int IO=1<<25;
    char ibuf[IO],*is=ibuf+IO,*it=ibuf+IO;
    #define gc (is==it)?(it=(is=ibuf)+fread(ibuf,1,IO,stdin),(is==it)?EOF:*is++):*is++
    il int rd(){
        ri int x=0;ri bool f=0;ri char c=gc;
        while(!isdigit(c)) f|=(c==45),c=gc;
        while(isdigit(c)) x=x*10+(c^48),c=gc;
        return f?-x:x;
    }
    char out[IO],*itr=out;
    #define Flush() fwrite(out,1,itr-out,stdout),itr=out
    short a[35],tl;
    il void wt(int x,char lastchar=10){
        if(x<0) (*itr++)=45,x=-x;
        do a[++tl]=x%10,x/=10; while(x);
        while(tl) (*itr++)=a[tl--]+48;
        (*itr++)=lastchar,Flush();
    }
} 

快速取模

struct fastmod{
    typedef unsigned long long u64;
    typedef __uint128_t u128;

    int m;
    u64 b;

    fastmod(int m) : m(m), b(((u128)1 << 64) / m) {}
    int reduce(u64 a){
        u64 q = ((u128)a * b) >> 64;
        int r = a - q * m;
        return r < m ? r : r - m;
    }
} z(2);

当模数为mod时,先在程序开始调用z=fastmod(mod),之后要计算一个在[0,264)内的整数nmod取模的结果时调用z.reduce(n),其返回值即是nmod取模的结果

具体使用方法如下(还是快了很多的)

#include <bits/stdc++.h>

using namespace std;

int n, mod;

struct fastmod{
    typedef unsigned long long u64;
    typedef __uint128_t u128;

    int m;
    u64 b;

    fastmod(int m) : m(m), b(((u128)1 << 64) / m) {}
    int reduce(u64 a){
        u64 q = ((u128)a * b) >> 64;
        int r = a - q * m;
        return r < m ? r : r - m;
    }
} z(2);

int main(){
    cin >> n >> mod;
    z = fastmod(mod);
    cout << z.reduce(n);
}

其他玄学卡常

  1. for循环里,++ii++大概快了一倍
  2. 经常调用的局部变量用register会快很多
  3. 函数前加inline,可以减少函数调用时间(递归加inline有出事风险)
  4. 函数传参加引用和const,也会快一些
  5. 三目运算符比if快(就是不太可读
  6. 常量表达式前加constexpr,可以在编译过程中就得到计算结果
  7. vector中,emplace_backpush_back省去了拷贝或移动元素的过程(可能快一些)
  8. 循环比递归快(但是递归好写啊
  9. 据说逗号比分号快(可能是迷信,优化不大)
  10. 位运算比普通运算快(虽然快不了多少,但是有时候写得比较方便
  11. 引用比返回值快(可能是真的,优化不大)
    to be continue~

edit

posted @   雨夜风月  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示