快读
整数快读
int read(){
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
快读的基本原理
-
字符流处理
快读函数直接使用
getchar()
逐个读取字符,避免了标准输入函数的类型解析和缓冲区开销。对于大规模数据(如百万级整数),这种方式的效率远高于scanf
或cin
。 -
手动解析整数
函数将连续的数字字符手动转换为整数,跳过非数字字符(如空格、换行符),并处理符号位(
-
)。 -
位运算优化
代码中
x = x*10 + c-'0';
是核心转换逻辑,相当于:- 将当前累计值
x
左移一位(乘以 10)。 - 将字符
c
转换为对应的数值(c-'0'
)。 - 累加得到新的数值。
- 将当前累计值
快读模板#不止整数
template <typename T>
inline void read(T &x) {
int c = getchar();
x = 0;
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9') {
x = x * 10 + (c - '0');
c = getchar();
}
}
关闭同步流(C++)
ios::sync_with_stdio(false);
cin.tie(nullptr);
二分查找
int ans=lower_bound(a+1,a+n+1,x)-a;//二分搜,注意-a
手搓版
int find(int x)
{
int l=1,r=n;
while (l<r)
{
int mid=l+(r-l)/2;
if (a[mid]>=x) r=mid;
else l=mid+1;
}
if (a[l]==x) return l;
else return -1;
}
循环展开
// 原始循环
for (int i = 0; i < n; ++i) {
sum += arr[i];
}
// 展开后的循环(假设 n 是 4 的倍数)
for (int i = 0; i < n; i += 4) {
sum += arr[i] + arr[i+1] + arr[i+2] + arr[i+3];
}
原理
- 减少分支预测错误 :
循环中的for/while
语句需要每次检查终止条件,展开后减少了条件判断次数。 - 提高指令级并行 :
CPU 可以同时处理多个操作(如sum += arr[i] + arr[i+1] + ...
),减少流水线停顿。 - 适用场景:循环次数固定且较大时效果显著(如处理数组)。
位运算优化#快速幂
x % 2 → x & 1
x / 2 → x >> 1
x * 2 → x << 1
// 快速幂
int pow(int a, int n) {
int res = 1;
while (n > 0) {
if (n & 1) res *= a;
a *= a;
n >>= 1;
}
return res;
}
内联函数
inline int add(int a, int b) {
return a + b;
}
一般情况,程序会自动内联,可以不用
预计算优化
// 预处理阶乘模数组
const int MOD = 1e9 + 7;
const int MAXN = 1e6;
long long fact[MAXN + 1];
void init() {
fact[0] = 1;
for (int i = 1; i <= MAXN; ++i) {
fact[i] = fact[i-1] * i % MOD;
}
}