#include #include #include #include #define REP(i,a,b) for(i=a;ik);if(i>=j)break;t=d[i];d[i]=d[j];d[j]=t;t=m1[i];m1[i]=m1[j];m1[j]=t;t=m2[i];m2[i]=m2[j];m2[j]=t;}intIntIntSort(d,m1,m2,i);intIntIntSort(d+j+1,m1+j+1,m2+j+1,s-j-1);} ll V[2222], U[2222], L[2222]; /* 0 = odd V[i] pouches (this is can be used as like 1,2,2 or 2,2,1) */ /* 1 = even V[i] pouches such that V[i] < 2*U[i] (this is can be used as like 1,2,2,1 or 2,2,2) */ /* 2 = even V[i] pouches such that V[i] = 2*U[i] (this is can be used as like only 2,2,2) */ int Ns[3]; ll Vs[3][2222], Us[3][2222], Ls[3][2222]; /* if tight, return res (total units eaten), otherwise return -1 */ /* A similar simulation is done here as in main function */ ll is_tight(ll day, ll eat, int cur_now[]){ int i; int fg; int cur[3]; ll late, val, now, mis; ll res; res = 0LL; rep(i,3) cur[i] = cur_now[i]; for(;;){ late = 0; rep(fg,3) if(cur[fg] >= 0 && late < Us[fg][cur[fg]]) late = Us[fg][cur[fg]]; if(late < day-eat) return -1; if(late && eat && late < day) return -1; if(late==0) break; if(eat==0){ for(fg=2;fg>=0;fg--) if(cur[fg]>=0 && day<=Us[fg][cur[fg]]) break; } else { for(fg=0;fg<=2;fg++) if(cur[fg]>=0 && day<=Us[fg][cur[fg]]) break; } mis = 0; if(eat && fg==2) mis = 1; now = day * 2 - eat; val = now; if(val > Vs[fg][cur[fg]]-mis) val = Vs[fg][cur[fg]]-mis; res += val; now -= val; cur[fg]--; if(now%2) day = now/2 + 1, eat = 1; else day = now/2, eat = 0; if(day==0) break; } return res; } int main(){ int T, N, Nsum = 0; int i, j, k; int fg; ll day, eat, late, val; ll now; ll res, sum, res_tmp, tryres; int cur[3]; assert( scanf("%d",&T)==1 ); assert( 1<=T && T<= 2013 ); while(T--){ assert( scanf("%d",&N)==1 ); Nsum += N; assert( 1<=N && N<=2013 ); assert( Nsum <= 20130 ); rep(i,N){ assert( scanf("%lld%lld%lld",V+i,U+i,L+i)==3 ); assert( 1LL<=V[i] && V[i]<=20000000000000LL ); assert( 1LL<=U[i] && U[i]<=20000000000000LL ); assert( 1LL<=L[i] && L[i]<=20000000000000LL ); } rep(i,N) rep(j,N) if(V[i] < V[j]) assert(U[i] <= U[j]); sum = 0; rep(i,N) sum += V[i]; rep(i,N) if(L[i] > U[i]) L[i] = U[i]; rep(i,N) if(V[i] > 2*L[i]) V[i] = 2*L[i]; rep(i,3) Ns[i] = 0; rep(i,N){ if(V[i]%2==1) fg = 0; else if(V[i] < 2*L[i]) fg = 1; else fg = 2; Vs[fg][Ns[fg]] = V[i]; Us[fg][Ns[fg]] = U[i]; Ls[fg][Ns[fg]] = L[i]; Ns[fg]++; } /* sort accourding to U, then V */ /* Us[0][i] <= Us[0][i+1] and Vs[0][i] <= Vs[0][i+1] */ /* Us[1][i] <= Us[1][i+1] and Vs[1][i] <= Vs[1][i+1] */ /* Us[2][i] <= Us[2][i+1] (but not Vs[2][i] <= Vs[2][i+1] here) */ rep(i,3) intIntIntSort(Us[i], Vs[i], Ls[i], Ns[i]); rep(i,3){ j = 0; while(j= 0 && late < Us[fg][cur[fg]]) late = Us[fg][cur[fg]]; if(day > late) day = late, eat = 0; if(day==0) break; if(eat==0){ /* we don't want to make eat = 1 */ for(fg=2;fg>=0;fg--) if(cur[fg]>=0 && day<=Us[fg][cur[fg]]) break; } else { /* we want to make eat = 0 */ for(fg=0;fg<=2;fg++) if(cur[fg]>=0 && day<=Us[fg][cur[fg]]) break; } if(eat==1 && fg==2){ /* be careful */ now = day * 2 - eat; val = now; if(val > Vs[fg][cur[fg]]-1) val = Vs[fg][cur[fg]]-1; now -= val; cur[fg]--; if(now%2) tryres = is_tight(now/2+1, 1, cur); /* false */ else tryres = is_tight(now/2, 0, cur); /* true */ cur[fg]++; if(tryres==-1){ now = day * 2 - eat - 1; /* only one unit eaten in this day, and open this pouch in next day */ val = now; if(val > Vs[fg][cur[fg]]) val = Vs[fg][cur[fg]]; res += val; now -= val; cur[fg]--; if(now%2) day = now/2 + 1, eat = 1; else day = now/2, eat = 0; } else { res += tryres + val; break; } } else { /* go straightfoward */ now = day * 2 - eat; val = now; if(val > Vs[fg][cur[fg]]) val = Vs[fg][cur[fg]]; res += val; now -= val; cur[fg]--; if(now%2) day = now/2 + 1, eat = 1; else day = now/2, eat = 0; } } res = sum - res; /* answer is total units of food - maximum unit of eaten food */ printf("%lld\n",res); } return 0; }