模板很重要!!!
模板是暴力的前提
暴力是骗分的重点
骗分是蒟蒻的目标
欧耶!
当你有了模板,暴力就信手拈来
当你有了模板,部分分手到擒来
当你有了模板,所有的问题都不再是问题
你还在为了考试时忘记模板而慌张吗?
你还在为正解不会,暴力写挂而烦恼吗?
别再烦恼!别再慌张!
手握模板,享受理想人生!
咳咳,以上太沙雕了,请跳过
注:以下都为手打
快速幂
O ( l o g 2 y ) O(log_2y) O(log2y)
inline ll Pow(ll x, ll y)
{
ll res = 1;
while (y)
{
if (y & 1) res = res * x % mod;
y >>= 1;
x = x * x % mod;
}
return res;
}
快速乘
O ( l o g 2 y ) O(log_2y) O(log2y)
inline ll mul(ll x, ll y)
{
ll res = 0;
while (y)
{
if (y & 1) res = (res + x) % mod;
y >>= 1;
x = (x + x) % mod;
}
return res;
}
组合数/排列数
inline ll Pow(ll x, ll y)
{
ll res = 1;
while (y)
{
if (y & 1) res = res * x % mod;
y >>= 1;
x = x * x % mod;
}
return res;
}
inline void pre_work()
{
fac[0] = 1;
for (int i = 1; i <= n; i++)
fac[i] = fac[i - 1] * i % mod;
inv[n] = Pow(fac[n], mod - 2);
for (int i = n - 1; i >= 0; i--)
inv[i] = inv[i + 1] * (i + 1) % mod;
}
inline ll C(int x, int y)
{
if (x < 0 || y < 0 || x < y) return 0;
return fac[x] * inv[y] % mod * inv[x - y] % mod;
}
inline ll A(int x, int y)
{
if (x < 0 || y < 0 || x < y) return 0;
return fac[x] * inv[x - y] % mod;
}
二分
O ( n l o g n ) O(nlogn) O(nlogn)
while (l <= r)
{
int mid = (l + r) >> 1;
if (check(mid)) l = mid + 1;
else r = mid - 1;
}
printf("%d\n", r);
while (l < r)
{
int mid = (l + r) >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
printf("%d\n", l);
while (l + 1 < r)
{
int mid = (l + r) >> 1;
if (check(mid)) r = mid;
else l = mid;
}
if (check(l)) printf("%d\n", l);
else printf("%d\n", r);
while (l <= r)
{
int mid = (l + r) >> 1;
if (check(mid)) ans = mid, l = mid + 1;
else r = mid - 1;
}
printf("%d\n", ans);
具体操作看题意
离散化
int a[N], b[N], cnt, n;
map <int, int> s;
inline void discrete()
{
cnt = 0;
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
b[i] = a[i];
}
sort(b + 1, b + 1 + n);
for (int i = 1; i <= n; i++)
if (!s[b[i]]) s[b[i]] = ++cnt;
}
求逆序对数(归并,树状数组)
O ( n l o g n ) O(nlogn) O(nlogn)
//归并排序
inline void merge(int l, int mid, int r)
{
int i = l, j = mid + 1;
for (int k = l; k <= r; k++)
if (j > r || i <= mid && a[i] <= a[j]) b[k] = a[i++];
else
{
b[k] = a[j++];
cnt += mid - i + 1;
}
for (int k = l; k <= r; k++)
a[k] = b[k];
}
inline void gb()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
cnt = 0;
merge(1, (1 + n) / 2, n);
printf("%d\n", cnt);
}
//树状数组
#define lowbit(x) x & (-x)
inline int ask(int x)
{
int res = 0;
for (; x; x -= lowbit(x)) res += c[x];
return res;
}
inline void add(int x, int y)
{
for (; x <= N; x += lowbit(x)) c[x] += y;
}
inline void BIT()
{
for (int i = n; i; i--)
{
ans += ask(a[i] - 1);
add(a[i], 1);
}
printf("%d\n", ans);
}
ST算法
O ( n l o g n ) O(nlogn) O(nlogn)
inline void ST_prework()
{
for (int i = 1; i <= n; i++)
f[i][0] = a[i];
int t = log(n) / log(2) + 1;
for (int j = 1; j < t; j++)
for (int i = 1; i <= n - (1 << j) + 1; i++)
f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}
inline int ST_query(int l, int r)
{
int k = log(r - l + 1) / log(2);
return max(f[l][k], f[r - (1 << k) + 1][k]);
}