Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC optimize ("O3")
- #pragma GCC target ("sse4")
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- typedef long double ld;
- typedef complex<ld> cd;
- typedef pair<int, int> pi;
- typedef pair<ll,ll> pl;
- typedef pair<ld,ld> pd;
- typedef vector<int> vi;
- typedef vector<ld> vd;
- typedef vector<ll> vl;
- typedef vector<pi> vpi;
- typedef vector<pl> vpl;
- typedef vector<cd> vcd;
- #define FOR(i, a, b) for (int i=a; i<(b); i++)
- #define F0R(i, a) for (int i=0; i<(a); i++)
- #define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
- #define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
- #define trav(a,x) for (auto& a : x)
- #define uid(a, b) uniform_int_distribution<int>(a, b)(rng)
- #define sz(x) (int)(x).size()
- #define mp make_pair
- #define pb push_back
- #define f first
- #define s second
- #define lb lower_bound
- #define ub upper_bound
- #define all(x) x.begin(), x.end()
- #define ins insert
- template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
- template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
- mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- const int MOD = 1000000007;
- const char nl = '\n';
- const int MX = 100001; //check the limits, dummy
- template<int SZ> struct DSU { //overkill!
- int parent[SZ], size[SZ];
- DSU() {
- F0R(i, SZ) parent[i] = i, size[i] = 0;
- }
- int get(int x) {
- if (parent[x] != x) parent[x] = get(parent[x]);
- return parent[x];
- }
- void unify(int x, int y) {
- x = get(x); y = get(y);
- if (x == y) return;
- if (size[x] < size[y]) swap(x, y);
- if (size[x] == size[y]) size[x]++;
- parent[y] = x;
- }
- };
- bool valid(int K) {
- if (K < 0 || K >= 48) return false;
- int X = K % 2; K /= 2;
- int Y = K % 3; K /= 3;
- if (Y == 2 && X == 0) return false;
- return K < (1 << (max(X, Y) + 1));
- }
- int getTrans(int s, int t) {
- if (!valid(s)) return -1;
- vi com;
- //bool pr = s == 11 && t == 9;
- com.pb(0); com.pb(s%2); s /= 2; com.pb(s%3); s /= 3;
- DSU<6> dsu;
- F0R(i, 3) {
- FOR(j, i+1, 3) {
- if (com[i] == com[j]) dsu.unify(i, j);
- }
- }
- F0R(i, 3) {
- if (t & (1 << i)) {
- dsu.unify(i, i+3);
- }
- }
- FOR(i, 3, 5) {
- if (t & (1 << i)) dsu.unify(i, i+1);
- }
- int nx = 1; if (dsu.get(4) == dsu.get(3)) nx = 0;
- int ny = nx + 1; if (dsu.get(5) == dsu.get(4)) ny = nx;
- if (dsu.get(5) == dsu.get(3)) ny = 0;
- int con[3]; F0R(i, 3) con[i] = -1;
- F0R(i, 3) {
- F0R(j, 3) {
- if (dsu.get(i) == dsu.get(j+3)) {
- if (j == 0) {
- con[com[i]] = 0;
- } else if (j == 1) {
- con[com[i]] = nx;
- } else {
- con[com[i]] = ny;
- }
- }
- }
- }
- int res = 0;
- F0R(i, 3) {
- if (s & (1 << i)) {
- if (con[i] == -1) return -1;
- res = res | (1 << con[i]);
- }
- }
- return res*6 + ny*2 + nx;
- }
- int add(int s, int t) {
- if (!valid(s)) return -1;
- int x = s % 2; s /= 2; int y = s % 3; s /= 3;
- if (t & 1) {
- s = s | 1;
- }
- if (t & 2) {
- s = s | (1 << x);
- }
- if (t & 4) {
- s = s | (1 << y);
- }
- return s*6 + y*2 + x;
- }
- void solve() {
- int trans[48][32]; F0R(i, 48) F0R(j, 32) trans[i][j] = getTrans(i, j);
- int N; cin >> N;
- int mask[N]; F0R(i, N) mask[i] = 0;
- int M; cin >> M;
- int H[N-1][3], V[N][2];
- F0R(i, 3) F0R(j, N-1) cin >> H[j][i];
- F0R(i, 2) F0R(j, N) cin >> V[j][i];
- F0R(i, M) {
- int X, Y; cin >> X >> Y; X--; Y--;
- mask[Y] += 1 << X;
- }
- ll dp[N][48]; F0R(i, N) F0R(j, 48) dp[i][j] = 1e18;
- dp[0][add(5, mask[0])] = 0;
- dp[0][add(2, mask[0])] = V[0][0];
- dp[0][add(3, mask[0])] = V[0][1];
- dp[0][add(0, mask[0])] = V[0][0] + V[0][1];
- F0R(i, N-1) {
- F0R(j, 48) {
- if (!valid(j)) continue;
- F0R(k, 32) {
- int nxt = trans[j][k]; nxt = add(nxt, mask[i+1]);
- ll cost = dp[i][j];
- F0R(x, 3) {
- if (k & (1 << x)) {
- cost += H[i][x];
- }
- }
- F0R(x, 2) {
- if (k & (1 << (x+3))) {
- cost += V[i+1][x];
- }
- }
- if (nxt != -1) ckmin(dp[i+1][nxt], cost);
- }
- }
- }
- ll ans = 1e18;
- F0Rd(i, N) {
- F0R(j, 48) {
- if (valid(j) && __builtin_popcount(j/6) == 1) ckmin(ans, dp[i][j]);
- }
- if (mask[i] > 0) break;
- }
- cout << ans << nl;
- }
- int main() {
- ios_base::sync_with_stdio(0); cin.tie(0);
- int T = 1;
- // cin >> T;
- while(T--) {
- solve();
- }
- return 0;
- }
- // read the question correctly (ll vs int)
- // template by bqi343
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement