关于卡常
关于卡常
快读
普通快读
众所周知,字符串输入输出比数字快,于是就有了以下快读
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,2^{64})\)内的整数\(n\)对\(mod\)取模的结果时调用\(z.reduce(n)\),其返回值即是\(n\)对\(mod\)取模的结果
具体使用方法如下(还是快了很多的)
#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);
}
其他玄学卡常
- 在\(for\)循环里,++\(i\)比\(i\)++大概快了一倍
- 经常调用的局部变量用\(register\)会快很多
- 函数前加\(inline\),可以减少函数调用时间(递归加\(inline\)有出事风险)
- 函数传参加引用和\(const\),也会快一些
- 三目运算符比\(if\)快(
就是不太可读) - 常量表达式前加\(constexpr\),可以在编译过程中就得到计算结果
- \(vector\)中,\(emplace\_back\)较\(push\_back\)省去了拷贝或移动元素的过程(可能快一些)
- 循环比递归快(
但是递归好写啊) - 据说逗号比分号快(
可能是迷信,优化不大) - 位运算比普通运算快(虽然快不了多少,
但是有时候写得比较方便) - 引用比返回值快(可能是真的,优化不大)
to be continue~
I went to the woods because I wanted to live deliberately, I wanted to live deep and suck out all the marrow of life, and not when I had come to die, discover that I had not live.