模拟赛-冬之花

冬之花

题意

给你一个 \(n + 2\) 个点的图,标号分别为 \(s, 1, 2, \ldots, N, t\),然后又三类边

  • \((s, i, s_i)\)
  • \((t, i, t_i)\)
  • \((i, i + 1, e_i)\) \(1\le i <N\)

\(N\le 10^ 9\)

题解

考虑怎么做。

这种东西,我们很明显就是要考虑等价。就你你考虑如果只有一个点,那么答案肯定是 \(\min(s_i, t_i)\),如果有多个点我们考虑把他们能不能缩成一个点考虑。

考虑这个转移。(可以立即为最大流等于最小割。)

\[\begin{bmatrix} s_i&s_i + e_i\\ t_i + e_i& t_i \end{bmatrix}\times \begin{bmatrix} s_{i+ 1} \\ t_{i + 1} \end{bmatrix} \]

这里的原来的矩阵乘法为 \((*,+)\),这里的矩阵乘法为 \((+,\min)\)

然后做完了

// Siriqwq
#include <bits/stdc++.h>
using std::cin;
using std::cout;
using std::vector;
using std::copy;
using std::reverse;
using std::sort;
using std::get;
using std::unique;
using std::swap;
using std::array;
using std::cerr;
using std::function;
using std::map;
using std::set;
using std::pair;
using std::mt19937;
using std::make_pair;
using std::tuple;
using std::make_tuple;
using std::uniform_int_distribution;
using ll = long long;
namespace qwq {
	mt19937 eng;
	void init(int Seed) {return eng.seed(Seed);}
	int rnd(int l = 1, int r = 1000000000) {return uniform_int_distribution<int> (l, r)(eng);}
}
template<typename T>
inline void chkmin(T &x, T y) {if (x > y) x = y;}
template<typename T>
inline void chkmax(T &x, T y) {if (x < y) x = y;}
template<typename T>
inline T min(const T &x, const T &y) {return x < y ? x : y;}
template<typename T>
inline T max(const T &x, const T &y) {return x > y ? x : y;}
char buf[100000], *bufs, *buft;
#define gc() ((bufs == buft && (buft = (bufs = buf) + fread(buf, 1, 100000, stdin))), bufs == buft ? -1 : *bufs++)
template<typename T>
inline void read(T &x) {
	x = 0;
	bool f = 0;
	char ch = gc();
	while (!isdigit(ch)) f = ch == '-', ch = gc();
	while (isdigit(ch)) x = x * 10 + ch - '0', ch = gc();
	if (f) x = -x;
}
inline void reads(char *s) {
	char ch = gc();
	while (isspace(ch)) ch = gc();
	while (!isspace(ch) && ch != EOF) *(s++) = ch, ch = gc();
	*s = 0;
	return;
}
template<typename T, typename ...Arg>
inline void read(T &x, Arg &... y) {
	read(x);
	read(y...);
}
#define O(x) cerr << #x << " : " << x << '\n'
const double Pi = acos(-1);
const int MAXN = 1 << 19, MOD = 998244353, inv2 = (MOD + 1) / 2, I32_INF = 0x3f3f3f3f;
const long long I64_INF = 0x3f3f3f3f3f3f3f3f;
auto Ksm = [] (int x, int y) -> int {
	if (y < 0) {
		y %= MOD - 1;
		y += MOD - 1;
	}
	int ret = 1;
	for (; y; y /= 2, x = (long long) x * x % MOD) if (y & 1) ret = (long long) ret * x % MOD;
	return ret;
};
auto Mod = [] (int x) -> int {
	if (x >= MOD) return x - MOD;
	else if (x < 0) return x + MOD;
	else return x;
};
template<const int N_num, const int M_num>
struct Graph {
	int H[N_num];
	struct Edge {int to, lac;} e[M_num];
	inline void add_edge(int x, int y) {e[*H] = {y, H[x]};H[x] = (*H)++;}
	inline void init() {memset(H, -1, sizeof H);*H = 0;}
};
#define go(x, y) for (int i = x.H[y], v; (v = x.e[i].to) && ~i; i = x.e[i].lac)
inline int ls(int k) {return k << 1;}
inline int rs(int k) {return k << 1 | 1;}
using ull = unsigned long long;
void add(int &x, int y) {if ((x += y) >= MOD) x -= MOD;}
struct Matrix {
	ll val[2][2];
	ll* operator [] (const int x) {return val[x];}
	Matrix operator * (Matrix a) {
		Matrix b;
		b[0][0] = min(val[0][0] + a[0][0], val[0][1] + a[1][0]);
		b[0][1] = min(val[0][0] + a[0][1], val[0][1] + a[1][1]);
		b[1][0] = min(val[1][0] + a[0][0], val[1][1] + a[1][0]);
		b[1][1] = min(val[1][0] + a[0][1], val[1][1] + a[1][1]);
		return b;
	}
} c9, nm[MAXN * 4];
int N, Q, s[MAXN], t[MAXN], e[MAXN], id[MAXN];
void build(int k, int l, int r) {
	if (l == r) {
		id[l] = k;
		nm[k][0][0] = s[l];
		nm[k][0][1] = s[l] + e[l];
		nm[k][1][0] = t[l] + e[l];
		nm[k][1][1] = t[l];
		return;
	}
	int mid = (l + r) / 2;
	build(ls(k), l, mid);
	build(rs(k), mid + 1, r);
	nm[k] = nm[ls(k)] * nm[rs(k)];
}
void mfy(int l) {
	int k = id[l];
	nm[k][0][0] = s[l];
	nm[k][0][1] = s[l] + e[l];
	nm[k][1][0] = t[l] + e[l];
	nm[k][1][1] = t[l];
	while (k > 1) {
		k /= 2;
		nm[k] = nm[ls(k)] * nm[rs(k)];
	}
}
Matrix qry(int k, int l, int r, int ql, int qr) {
	if (ql <= l && r <= qr) return nm[k];
	int mid = (l + r) / 2;
	if (qr <= mid) return qry(ls(k), l, mid, ql, qr);
	if (mid < ql) return qry(rs(k), mid + 1, r, ql, qr);
	return qry(ls(k), l, mid, ql, qr) * qry(rs(k), mid + 1, r, ql, qr);
}
int main() {
	freopen("hana.in", "r", stdin);
	freopen("hana.out", "w", stdout);
	// std::ios::sync_with_stdio(0);
	// cout << std::fixed << std::setprecision(8);
	// cin.tie(0);
	// cout.tie(0);
	qwq::init(20050217);
	read(N, Q);
	for (int i = 1; i <= N; ++i) read(s[i]);
	for (int i = 1; i <= N; ++i) read(t[i]);
	for (int i = 1; i < N; ++i) read(e[i]);
	if (N > 1) build(1, 1, N - 1);
	for (int opt, x, y; Q--; ) {
		read(opt, x, y);
		if (opt == 1) {
			s[x] = y;
			if (x < N) mfy(x);
		} else if (opt == 2) {
			t[x] = y;
			if (x < N) mfy(x);
		} else if (opt == 3) {
			e[x] = y;
			if (x < N) mfy(x);
		} else {
			if (x == y) printf("%d\n", min(s[x], t[x]));
			else {
				c9[0][0] = s[y];
				c9[1][0] = t[y];
				c9 = qry(1, 1, N - 1, x, y - 1) * c9;
				printf("%lld\n", min(c9[0][0], c9[1][0]));
			}
		}
	}
	// cout << (-3 / 2);
	cerr << ((double) clock() / CLOCKS_PER_SEC) << '\n';
	return (0-0);
}

posted @ 2022-08-02 15:48  siriehn_nx  阅读(137)  评论(2编辑  收藏  举报