模拟赛-冬之花
冬之花
题意
给你一个 \(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);
}