闲话 22.11.10
闲话
所以我的代码头终于史诗级加长了
写标程写挂怎么办啊
盯着这题突然想到
嗯你救下了学姐。然后在车站学姐把杏子崩了。然后小圆把学姐毙了。
城市没有消亡,但这一切值得吗?
今天虎哥放了《In the hell we live, Lament》
虎哥睿评:好奇怪 戛然而止
突然想听《命运》了
杂题
水水水
给出一个数列 \(a\),有 \(q\) 个操作,每种操作是把区间 \([l,r]\) 中等于 \(x\) 的数改成 \(y\)。输出 \(q\) 步操作完的数列。
\(1\le n,a_i\le 2\times 10^5\)。
分块。
到这把代码贺过来就能切了。
记得删掉没用的数组。
以及我是调完块长后才发现 \(a_i \le 100\) 所以可以随意设块长的(
936ms (
似乎比一部分线段树要快嗯
↓这代码是直接贺来的所以不像最近的代码
code
#include <cstdio>
#include <cstring>
#include <cassert>
#include <algorithm>
using namespace std;
#define mod 998244353
#define N 200005
#define siz 450
#define rep(i,a,b) for ( register int (i) = (a); (i) <= (b); ++(i) )
#define pre(i,a,b) for ( register int (i) = (a); (i) >= (b); --(i) )
int n, q, a[N];
int bl[N], sz[N / siz + 5], st[N / siz + 5], ed[N / siz + 5];
inline int qp(int a, int b) {
int ret = 1;
while (b) {
if (b & 1) ret = 1ll * ret * a % mod;
a = 1ll * a * a % mod;
b >>= 1;
} return ret;
}
struct block_id {
int viv, cnt;
}g[N / siz + 5][105];
int fa[N], v[N];
inline int get(int x) {
return x == fa[x] ? x : fa[x] = get(fa[x]);
}
inline void init(int id) {
rep(i, st[id], ed[id]) {
if (g[id][a[i]].viv) fa[i] = g[id][a[i]].viv, g[id][a[i]].cnt++;
else fa[i] = g[id][a[i]].viv = i, v[i] = a[i], g[id][a[i]].cnt = 1;
}
}
inline void ps_d(int id) {
rep(i, st[id], ed[id]) {
a[i] = v[get(i)];
g[id][a[i]].viv = g[id][a[i]].cnt = 0;
} rep(i, st[id], ed[id]) fa[i] = 0;
}
inline void deal_side(int id, int l, int r, int from, int to) {
ps_d(id);
rep(i, l, r) if(a[i] == from) a[i] = to;
init(id);
}
inline void deal_whole(int id, int from, int to) {
g[id][to].cnt += g[id][from].cnt;
if (g[id][to].viv == 0) g[id][to].viv = g[id][from].viv, v[g[id][to].viv] = to;
else fa[g[id][from].viv] = g[id][to].viv;
g[id][from].cnt = g[id][from].viv = 0;
}
inline void change(int l, int r, int from, int to) {
if (bl[l] == bl[r]) {
deal_side(bl[l], l, r, from, to);
} else {
int lf, rt;
if (st[bl[l]] != l) {
deal_side(bl[l], l, ed[bl[l]], from, to);
lf = bl[l] + 1;
} else {
lf = bl[l];
} if (ed[bl[r]] != r) {
deal_side(bl[r], st[bl[r]], r, from, to);
rt = bl[r] - 1;
} else {
rt = bl[r];
}
rep(i, lf, rt) deal_whole(i, from, to);
}
}
signed main() {
register int opr, l, r, x, y;
cin >> n;
rep(i,1,n) bl[i] = (i-1) / siz + 1;
rep(i,1,bl[n] - 1) sz[i] = siz;
sz[bl[n]] = ((n % siz == 0) ? siz : n % siz);
st[1] = 1;
rep(i,2,bl[n]) st[i] = st[i-1] + sz[i-1];
rep(i,1,bl[n]-1) ed[i] = st[i+1] - 1;
ed[bl[n]] = n;
rep(i,1,n) cin >> a[i];
rep(i,1,bl[n]) init(i);
cin >> q;
rep(i,1,q) {
cin >> l >> r >> x >> y;
if (x == y) continue;
change(l, r, x, y);
}
rep(i,1,bl[n]) ps_d(i);
rep(i,1,n) cout << a[i] << ' ';
}
有一个\(n\times m\) 的矩阵, 现在你正位于左上角的格子, 并且你只能向右移动或向下移动, 不幸的是, 矩阵的左下角\(a*b\) 的地方被划为了禁区, 即你不能在此行走, 那么现在你有多少种方法从左上角走到右下角的格子呢?
考虑没有限制的情况。
Schroder 数即可。
\(\text{Schroder}\) 数
用于格路计数。仅可以向右向下走,从 \((x_1, y_1)\) 到 \((x_2,y_2)\) 的方案数为
\[\binom{x_2-x_1+y_2-y_1}{x_2-x_1} \]
然后现在有限制。
其实差不多。我们看横坐标为 \(a\),纵坐标在 \(b\sim n\) 间的格点。可以以这些点作为中转点将所有可能的路径划分成两部分,这两部分都是格路,可以用 Schroder 数计算。
做完了。
↓这代码是最新的(
code
#include <bits/stdc++.h>
using namespace std; using ll = long long; using ull = unsigned long long; using db = double; using ld = long double; using lll = __int128_t;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
template<typename T> void get(T & x) {
x = 0; char ch = getchar(); bool f = false; while (ch < '0' or ch > '9') f = f or ch == '-', ch = getchar();
while ('0' <= ch and ch <= '9') x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); f && (x = -x);
} template <typename T, typename ... Args> void get(T & a, Args & ... b) { get(a); get(b...); }
#define rep(i,s,t) for (register int i = (s), i##_ = (t) + 1; i < i##_; ++ i)
#define pre(i,s,t) for (register int i = (s), i##_ = (t) - 1; i > i##_; -- i)
const int N = 2e5 + 10;
// const int B = 300;
// const int mod = 469762049, g = 3;
// const int mod = 998244353, g = 3;
// const int mod = 1004535809, g = 3;
const int mod = 1e9 + 7;
// const int mod = 1e9 + 9;
// const int mod = 1e9 + 3579, bse = 131;
const int inv2 = (mod + 1) >> 1;
template <typename T1, typename T2> T1 add(T1 a, T2 b) { return (a += b) >= mod ? a - mod : a; }
template <typename T1, typename ...Args> T1 add(T1 a, Args ... b) { return add(a, add(b...)); }
struct FastMod { int m; ll b; void init(int _m) { m = _m; b = ((lll)1<<64) / m; } FastMod(int _m) { init(_m); } int operator() (ll a) {ll q = ((lll)a * b) >> 64; a -= q * m; if (a >= m) a -= m; return a; } } Mod(mod);
int mul(int a, int b) { return Mod(1ll * a * b); } template <typename ...Args> int mul(int a, Args ...b) { return mul(a, mul(b...)); }
// int mul(int a, int b) { return 1ll * a * b % mod; } template <typename ...Args> int mul(int a, Args ...b) { return mul(a, mul(b...)); }
template <typename T1, typename T2> T1 qp(T1 a, T2 b) { T1 ret = 1; for (; b; a = mul(a, a), b >>= 1) if (b & 1) ret = mul(ret, a); return ret; }
int n, m, a, b, ans;
int fac[N], inv[N];
int C(int n, int m) { if (n == m or m == 0) return 1; return mul(fac[n], inv[m], inv[n - m]); }
int Sch(int x1, int y1, int x2, int y2) { return C(x2 - x1 + y2 - y1, x2 - x1); }
int main() {
get(n, m, a, b);
fac[0] = inv[0] = fac[1] = inv[1] = 1;
rep(i,2,n + m + 1) fac[i] = mul(fac[i - 1], i), inv[i] = mul(mod - mod / i, inv[mod % i]);
rep(i,2,n + m + 1) inv[i] = mul(inv[i], inv[i - 1]);
rep(i,1,n - a) {
ans = add(ans, mul(Sch(1, 1, i, b), Sch(i, b + 1, n, m)));
} cout << ans << endl;
}
以下是博客签名,与正文无关。
请按如下方式引用此页:
本文作者 joke3579,原文链接:https://www.cnblogs.com/joke3579/p/chitchat221110.html。
遵循 CC BY-NC-SA 4.0 协议。
请读者尽量不要在评论区发布与博客内文完全无关的评论,视情况可能删除。