#include<bits/stdc++.h> using namespace std; const int maxn=200009; long long tab[maxn], n, minim[maxn]; long long dwojki(long long x) { return min((long long)1000000000, x*(x-1)/2); } long long trojki(long long x) { return min((long long)1000000000, x*(x-1)*(x-2)/6); } long long binsearch(long long prog, long long poprzedni, long long x) { long long p, k, sr, poprz, tu, nast, wynik; p=poprzedni+1; k=x+1; while(p<k) { sr=(p+k)>>1; poprz=poprzedni; tu=sr-poprz; nast=x-sr; wynik=min((long long)1000000000, min((long long)1000000000, poprz*tu)*nast); wynik=min((long long)1000000000, wynik+dwojki(tu)*(poprz+nast)); wynik=min((long long)1000000000, wynik+trojki(tu)); if(wynik>=prog) { k=sr; } else { p=sr+1; } } return p; } bool sprawdz(long long x) { //pierwszy //srodek for(long long i=1; i<=n; i++) { minim[i]=0; if(tab[i]==0) { minim[i]=minim[i-1]; continue; } minim[i]=binsearch(tab[i], minim[i-1], x); } if(minim[n]>x) { return 0; } return 1; //ostatni } void solve() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n; for(long long i=1; i<=n; i++) { cin >> tab[i]; } long long p, k, sr; p=3; k=1000000000;///jaki upper bound?? while(p<k) { sr=(p+k)>>1; if(sprawdz(sr)) { k=sr; } else { p=sr+1; } } cout << p << '\n'; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int t; cin >> t; for(int i=1; i<=t; i++) { solve(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | #include<bits/stdc++.h> using namespace std; const int maxn=200009; long long tab[maxn], n, minim[maxn]; long long dwojki(long long x) { return min((long long)1000000000, x*(x-1)/2); } long long trojki(long long x) { return min((long long)1000000000, x*(x-1)*(x-2)/6); } long long binsearch(long long prog, long long poprzedni, long long x) { long long p, k, sr, poprz, tu, nast, wynik; p=poprzedni+1; k=x+1; while(p<k) { sr=(p+k)>>1; poprz=poprzedni; tu=sr-poprz; nast=x-sr; wynik=min((long long)1000000000, min((long long)1000000000, poprz*tu)*nast); wynik=min((long long)1000000000, wynik+dwojki(tu)*(poprz+nast)); wynik=min((long long)1000000000, wynik+trojki(tu)); if(wynik>=prog) { k=sr; } else { p=sr+1; } } return p; } bool sprawdz(long long x) { //pierwszy //srodek for(long long i=1; i<=n; i++) { minim[i]=0; if(tab[i]==0) { minim[i]=minim[i-1]; continue; } minim[i]=binsearch(tab[i], minim[i-1], x); } if(minim[n]>x) { return 0; } return 1; //ostatni } void solve() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n; for(long long i=1; i<=n; i++) { cin >> tab[i]; } long long p, k, sr; p=3; k=1000000000;///jaki upper bound?? while(p<k) { sr=(p+k)>>1; if(sprawdz(sr)) { k=sr; } else { p=sr+1; } } cout << p << '\n'; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int t; cin >> t; for(int i=1; i<=t; i++) { solve(); } } |