快速读入
inline int read() {
int s = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
s = s * 10 + ch - '0';
ch = getchar();
}
return s * f;
}
快速幂
int ksm(int a, int n) {
int ans = 1;
while(n) {
if(n & 1) ans *= a;
a *= a;
n >>= 1;
}
return ans;
}
射线法
射线法是一个常用的判断某个点是否在一个封闭图形内部的方法
原理可以自己证明,总之就是:以某个点向上下左右某个方向作射线。如果这条射线与这个图形的交点为奇数个,那么就在封闭图形里,否则就不在封闭图形里。
其实也没有必要记得很明白,在考场上画个正方形,在里面找个点作射线看看有几个焦点就好了。
位运算
二进制上面的运算,一般有以下几个操作:
操作 | 写法 |
---|---|
去掉最后一位 | x > > 1 x >> 1 x>>1 |
在最后加一个 1 1 1 | x < < 1 + 1 x << 1 + 1 x<<1+1 |
在最后加一个 0 0 0 | x < < 1 x << 1 x<<1 |
把最后一位变成 1 1 1 | x ∣ 1 x | 1 x∣1 |
把最后一位变成 0 0 0 | x ∣ 1 − 1 x | 1 - 1 x∣1−1 |
最后一位取反 | x x x ^ 1 1 1 |
把从右数第 k k k位变成 1 1 1 | x ∣ ( 1 < < ( k − 1 ) ) x | (1 << (k - 1)) x∣(1<<(k−1)) |
把从右数第 k k k位变成 0 0 0 | x & x \& x& ~ ( 1 < < ( k − 1 ) ) (1 << (k - 1)) (1<<(k−1)) |
从右数第 k k k为取反 | x x x ^ ( 1 < < ( k − 1 ) ) (1 << (k - 1)) (1<<(k−1)) |
取末尾 k k k位 | x & ( 1 < < ( k − 1 ) ) x \& (1 << (k - 1)) x&(1<<(k−1)) |
取从右数第 k k k位 | x > > ( k − 1 ) & 1 x >> (k - 1) \& 1 x>>(k−1)&1 |
把末尾 k k k位变成 1 1 1 | x ∣ ( 1 < < ( k − 1 ) ) x | (1 << (k - 1)) x∣(1<<(k−1)) |
把末尾 k k k位取反 | x x x ^ ( 1 < < ( k − 1 ) ) (1 << (k - 1)) (1<<(k−1)) |
把右边连续的 1 1 1变成 0 0 0 | x & ( x + 1 ) x \& (x + 1) x&(x+1) |
把从右数第一个 0 0 0变成 1 1 1 | x ∣ ( x + 1 ) x | (x + 1) x∣(x+1) |
把右边连续的 0 0 0变成 1 1 1 | x ∣ ( x − 1 ) x | (x - 1) x∣(x−1) |
取右边连续的 1 1 1 | x x x ^ ( x + 1 ) > > 1 (x + 1) >> 1 (x+1)>>1 |
去掉从右数第一个 1 1 1的左边 | x & ( − x ) x \& (-x) x&(−x) |