// Author: Lech Duraj // O(k! log n + n log n) #include #include #include #include using namespace std; typedef pair PI; int n; vector A; const int infty = 1000*1000*1000; #define dprintf(...) //#define dprintf(...) fprintf(stderr,__VA_ARGS__) struct tree { vector check, value; vector T; int M; int setval(int k, int v) { value[k] = v; int x = (M+k)/2; while(x>=1) { if (value[T[2*x]]>=value[T[2*x+1]]) T[x] = T[2*x]; else T[x] = T[2*x+1]; x /= 2; } } void init(int n) { M = 1; while(M<=n+1) M *= 2; check.clear(); check.resize(M,infty+1); value.clear(); value.resize(M,-infty); T.clear(); T.resize(2*M); for(int i=0; i1) { if (x%2!=0 && value[T[x-1]]>value[best]) best = T[x-1]; x /= 2; } return best; } }; tree tree1, tree2; void start() { tree1.init(n); tree2.init(n); for(int i=0; i &sol) { sol.clear(); if (k==0) { int best_diff = tree1.query(infty-1); sol.push_back(best_diff); return A[best_diff].first - A[best_diff].second; } vector sol_part; int c = go(k-1,sol_part); int current = -infty+1; for(int r : sol_part) { vector sol_o; remove(r); int other = go(k-1, sol_o); if (A[r].first<=other) other = A[r].first - A[r].second; else other = other - A[r].second; sol_o.push_back(r); if (other>current) { sol = sol_o; current = other; } add(r); } for (int r : sol_part) remove(r); int best1 = tree1.query(c); int best2 = tree2.query(-c); int val1 = tree1.value[best1]; int val2 = tree2.value[best2]; if (val2 != -infty) val2 += c; best2 = n-1-best2; if (val1>=val2 && val1>current) { sol = sol_part; current = val1; sol.push_back(best1); } if (val1current) { sol = sol_part; current = val2; sol.push_back(best2); } for(int r : sol_part) add(r); return current; } int main() { int TT; scanf("%d",&TT); while(TT--) { int k; scanf("%d %d",&n,&k); A.resize(n); for(int i=0; i sol; printf("%d\n",max(go(k,sol),0)); } }