#line 1 "e.cpp" #include using namespace std; using ll=long long; const ll ILL=2167167167167167167; const int INF=2100000000; #define rep(i,a,b) for (int i=(int)(a);i<(int)(b);i++) #define all(p) p.begin(),p.end() template using _pq = priority_queue, greater>; template int LB(vector &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();} template int UB(vector &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();} template bool chmin(T &a,T b){if(b bool chmax(T &a,T b){if(a void So(vector &v) {sort(v.begin(),v.end());} template void Sore(vector &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});} bool yneos(bool a,bool upp=false){if(a){cout<<(upp?"YES\n":"Yes\n");}else{cout<<(upp?"NO\n":"No\n");}return a;} template void vec_out(vector &p,int ty=0){ if(ty==2){cout<<'{';for(int i=0;i<(int)p.size();i++){if(i){cout<<",";}cout<<'"'< T vec_min(vector &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmin(ans,x);return ans;} template T vec_max(vector &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmax(ans,x);return ans;} template T vec_sum(vector &a){T ans=T(0);for(auto &x:a) ans+=x;return ans;} int pop_count(long long a){int res=0;while(a){res+=(a&1),a>>=1;}return res;} template T square(T a){return a * a;} // https://nyaannyaan.github.io/library/dp/monge-d-edge-shortest-path.hpp #line 2 "dp/monge-d-edge-shortest-path.hpp" #line 2 "dp/golden-section-search.hpp" #line 35 "e.cpp" using namespace std; // reference:https://twitter.com/noshi91/status/1399003086362865673 namespace golden_section_search_impl { using i64 = long long; // [min, max] は閉区間を入力する template pair golden_section_search(const function& f, i64 min, i64 max) { assert(min <= max); i64 a = min - 1, x, b; { i64 s = 1, t = 2; while (t < max - min + 2) swap(s += t, t); x = a + t - s, b = a + t; } T fx = f(x), fy; while (a + b != 2 * x) { i64 y = a + b - x; if (max < y || (fy = f(y), get_min ? fx < fy : fx > fy)) { b = a; a = y; } else { a = x; x = y; fx = fy; } } return {x, fx}; } } // namespace golden_section_search_impl using golden_section_search_impl::golden_section_search; /* @brief 黄金分割探索 */ #line 2 "dp/monge-shortest-path.hpp" #line 80 "e.cpp" using namespace std; // https://noshi91.hatenablog.com/entry/2023/02/18/005856 // 辺コストが monge である DAG の 0 - i 最短路 template vector monge_shortest_path(int N, const function& f) { T INF = (T{1} << (sizeof(T) * 8 - 2)) - 1; vector dp(N + 1, INF); vector x(N + 1, 0); auto check = [&](int from, int to) { if (from >= to) return; T cost = f(from, to); if (dp[from] + cost < dp[to]) dp[to] = dp[from] + cost, x[to] = from; }; auto dfs = [&](auto rc, int l, int r) -> void { if (l + 1 >= r) return; int m = (l + r) / 2; for (int i = x[l]; i <= x[r]; i++) check(i, m); rc(rc, l, m); for (int i = l + 1; i <= m; i++) check(i, r); rc(rc, m, r); }; dp[0] = 0, check(0, N), dfs(dfs, 0, N); return dp; } /** * @brief monge グラフ上の最短路 */ #line 5 "dp/monge-d-edge-shortest-path.hpp" // 辺コストが monge である DAG の D 辺 0-N 最短路 // f : from -> to のコスト (long long) // upper : max abs(辺数を 1 増減させたときのコストの変化) // (内部で int128 で計算しているので upper は 1e18 でも壊れない) long long monge_d_edge_shortest_path(int N, int D, long long upper, const function& f) { using T = __int128_t; upper = abs(upper); auto dp = [&](long long x) -> T { auto g = [&](int from, int to) -> T { return f(from, to) + x; }; T cost = monge_shortest_path(N, g)[N]; return cost - T{1} * D * x; }; auto [_, res] = golden_section_search(dp, -upper, upper); return res; } /** * @brief monge グラフ上の d-辺最短路 */ #line 4 "/Users/Shared/po167_library/ds/Sparse_table.hpp" namespace po167{ template struct Sparse_table{ int n; int depth; std::vector> val; void init(std::vector &v){ depth = 1; n = v.size(); while ((1 << depth) <= n) depth++; val.resize(depth); val[0] = v; for (int i = 1; i < depth; i++){ val[i].resize(n); for (int j = 0; j <= n - (1 << i); j++){ val[i][j] = op(val[i - 1][j], val[i - 1][j + (1 << (i - 1))]); } } } Sparse_table(std::vector v){ init(v); } Sparse_table(){} // 0 <= l < r <= n // if l == r : assert T prod(int l, int r){ assert(0 <= l && l < r && r <= n); int z=31-__builtin_clz(r-l); return op(val[z][l], val[z][r - (1 << z)]); } }; } #line 133 "e.cpp" ll op(ll a, ll b){ return max(a, b); } void solve(); // POP'N ROLL MUSIC / TOMOO int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t = 1; cin >> t; rep(i, 0, t) solve(); } void solve(){ ll N, K; cin >> N >> K; vector A(N), B(N); rep(i, 0, N) cin >> A[i]; rep(i, 0, N) cin >> B[i]; const ll lim = (1ll << 50); ll save = 0; if (K % 2 == 0){ A.push_back(lim); A.push_back(0); B.push_back(0); B.push_back(lim); K++; N += 2; save = 1; } K /= 2; K++; vector SA(N + 1), SB(N + 1), D(N + 1); rep(i, 0, N){ SA[i + 1] = A[i] + SA[i]; SB[i + 1] = B[i] + SB[i]; D[i + 1] = SA[i] - SB[i]; } po167::Sparse_table S(D); auto f = [&](int l, int r) -> ll { ll res = SB[r] - SA[l]; res += S.prod(l, r + 1); return - res; }; ll ans = monge_d_edge_shortest_path(N, K, ILL, f); ans *= -1; if (save) ans -= lim * 2; cout << ans << "\n"; } /* * i -> i + 1 のときに、同じなら +- 0 とすると * A -> B への移動のコスト * B -> A への移動のコストがわかる * i -> i + 1 の移動コストを */