#include using namespace std; #define sim template < class c #define ris return * this #define dor > debug & operator << #define eni(x) sim > typename \ enable_if(0) x 1, debug&>::type operator<<(c i) { sim > struct rge {c b, e; }; sim > rge range(c i, c j) { return rge{i, j}; } sim > auto dud(c* x) -> decltype(cerr << *x, 0); sim > char dud(...); struct debug { #ifdef LOCAL ~debug() { cerr << endl; } eni(!=) cerr << boolalpha << i; ris; } eni(==) ris << range(begin(i), end(i)); } sim, class b dor(pair < b, c > d) { ris << "(" << d.first << ", " << d.second << ")"; } sim dor(rge d) { *this << "["; for (auto it = d.b; it != d.e; ++it) *this << ", " + 2 * (it == d.b) << *it; ris << "]"; } #else sim dor(const c&) { ris; } #endif }; #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " const int INF = 1e9 + 5; const int nax = 1e5 + 5; int in[nax][4]; long long answer = 0; #define mini(a, b) a = min(a, (b)) vector forward_bfs(int low, int high) { vector d(high - low + 1, INF); d[0] = 0; for(int i = low; i <= high; ++i) for(int j = 1; j <= 3 && i + j <= high; ++j) mini(d[i + j - low], d[i - low] + in[i][j]); for(int x : d) answer += x; return d; } vector backward_bfs(int low, int high) { vector d(high - low + 1, INF); d.back() = 0; for(int i = high; i >= low; --i) for(int j = 1; j <= 3 && i - j >= low; ++j) mini(d[i - j - low], d[i - low] + in[i-j][j]); for(int x : d) answer += x; return d; } void rec(int low, int high) { if(low == high) return; if(abs(low - high) <= 4) { forward_bfs(low, high); rec(low + 1, high); return; } int b = (low + high) / 2; int a = b - 1; int c = b + 1; rec(low, a - 1); rec(c + 1, high); vector> distances; for(int x : vector{a, b, c}) { distances.push_back(backward_bfs(low, x)); distances.push_back(forward_bfs(x, high)); } debug() << imie(distances); answer -= in[a][1] + in[b][1] + distances[1][2]; // because counted twice vector> left, right; for(int i = 0; i < a - low; ++i) left.push_back(vector{distances[0][i], distances[2][i], distances[4][i]}); #define last(vec, i) vec[(int) vec.size() - i] for(int i = 1; i <= high - c; ++i) right.push_back(vector{last(distances[1], i), last(distances[3], i), last(distances[5], i)}); #undef last assert((int) left.size() + (int) right.size() + 3 == high - low + 1); debug() << imie(left) << imie(right); for(int which = 0; which < 3; ++which) { auto getPair = [&] (const vector & vec) { assert((int) vec.size() == 3); vector tmp2; for(int i = 0; i < 3; ++i) if(i != which) tmp2.push_back(vec[i] - vec[which]); return make_pair(tmp2[0], tmp2[1]); }; vector> one, two; for(const vector & vec : left) one.push_back(getPair(vec)); for(const vector & vec : right) two.push_back(getPair(vec)); debug() << imie(which) << imie(one) << imie(two); for(int twice = 0; twice < 2; ++twice) { swap(left, right); swap(one, two); /*for(int i = 0; i < (int) one.size(); ++i) for(pair other : two) if(one[i].first >= -other.first && one[i].second >= -other.second) answer += left[i][which];*/ // segment tree vector, int>> events; for(int i = 0; i < (int) one.size(); ++i) events.push_back({one[i], left[i][which]}); for(pair & p : two) events.push_back({{-p.first, -p.second}, 0}); vector> scaled; for(int i = 0; i < (int) events.size(); ++i) scaled.push_back({events[i].first.second, i}); sort(scaled.begin(), scaled.end()); int tmp_pointer = 0; for(int i = 0; i < (int) scaled.size(); ++i) { if(i && scaled[i].first != scaled[i-1].first) ++tmp_pointer; events[scaled[i].second].first.second = tmp_pointer; } sort(events.begin(), events.end()); int pot = 1; while(pot <= (int) events.size()) pot *= 2; vector tr(2 * pot, 0); for(pair, int> & p : events) { if(p.second) { int cnt = 0; for(int x = pot + p.first.second + 1; x >= 2; x /= 2) { debug() << imie(x); if(x % 2 == 1) cnt += tr[x - 1]; } answer += (long long) cnt * p.second; } else { debug() << "start"; for(int x = pot + p.first.second; x >= 1; x /= 2) { ++tr[x]; debug() << "ple" << imie(x); } } } } // deal with ties for(vector & vec : left) vec[which]--; } /*for(auto & one : left) for(auto & two : right) answer += min({one[0] + two[0], one[1] + two[1], one[2] + two[2]});*/ } void te() { answer = 0; int n; scanf("%d", &n); for(int j = 1; j <= 3; ++j) for(int i = 1; i <= n - j; ++i) scanf("%d", &in[i][j]); rec(1, n); printf("%lld\n", answer); } int main() { int T; scanf("%d", &T); while(T--) te(); }