闲话 22.11.10

闲话

所以我的代码头终于史诗级加长了

写标程写挂怎么办啊

盯着这题突然想到
嗯你救下了学姐。然后在车站学姐把杏子崩了。然后小圆把学姐毙了。
城市没有消亡,但这一切值得吗?

今天虎哥放了《In the hell we live, Lament》
虎哥睿评:好奇怪 戛然而止
突然想听《命运》了

杂题

水水水

CF911G

给出一个数列 \(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] << ' ';
}



ARC058D

有一个\(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;
}
posted @ 2022-11-10 19:32  joke3579  阅读(86)  评论(6编辑  收藏  举报