Problem:
安全点検
JOI 市には
1
本の十分に長い道路がある．この道路は数直線とみなすことができ，各地点は
1
個の実数による座標で表される．また JOI 市にはこの道路に沿って
N
個の施設が設置されており，座標の小さい順に
1
から
N
までの番号がつけられている．施設
i
(
1 ≦ i ≦ N
) の位置は座標
A
i
である．
JOI 市ではこれから施設の安全点検が行われる．施設
i
には点検しなければならない項目が
B
i
個ある．今，点検を行うことができる
K
人の大工が集められた．安全点検の開始のとき，大工は全員が座標
0
にいる．点検が始まると，各大工は
1
分間で，次の
2
つの行動のどちらかをとることができる．
距離
1
だけ座標を移動する．
今いる座標にある施設の点検項目のうち，
1
個の項目を選んで点検する．
安全点検を終えるとき，すべての建物のすべての点検項目が，
1
人以上の大工によって点検されていなければならない．
大工の人数と施設の情報が与えられるので，安全点検を終えるのに最短で何分かかるかを求めるプログラムを作成せよ．
制約
1 ≦ N ≦ 100000
．
1 ≦ K ≦ 10
9
．
1 ≦ A
i
≦ 10
9
(
1 ≦ i ≦ N
)．
A
i
< A
i+1
(
1 ≦ i ≦ N-1
)．
1 ≦ B
i
≦ 10
9
(
1 ≦ i ≦ N
)．
入力される値はすべて整数である．
入力
入力は以下の形式で標準入力から与えられる．
N
K
A
1
A
2
…
A
N
B
1
B
2
…
B
N
出力
標準出力に，安全点検を終えるのに最短で何分かかるかを
1
行で出力せよ．
入出力例
入力例 1
3 3
1 3 4
4 2 4
出力例 1
7
例えば，以下のように行動することで，
7
分間で点検を終えることができる．ただし
3
人の大工に番号をつけて，それぞれ大工
1,2,3
と表す．
大工
1,2,3
が座標
1
に移動する．
大工
1,2,3
がそれぞれ施設
1
の点検を
1
項目ずつ行う．
大工
1,2
が座標
2
に移動し，大工
3
が施設
1
の点検を
1
項目行う．
大工
1,2
が座標
3
に移動し，大工
3
が座標
2
に移動する．
大工
1,2
が座標
4
に移動し，大工
3
が座標
3
に移動する．
大工
1,2
がそれぞれ施設
3
の点検を
1
項目ずつ行い，大工
3
が施設
2
の点検を
1
項目行う．
大工
1,2
がそれぞれ施設
3
の点検を
1
項目ずつ行い，大工
3
が施設
2
の点検を
1
項目行う．
どのように行動しても
7
分未満で点検を終えることはできないので
7
を出力する．
入力例 2
6 1
1 4 5 6 11 15
12 5 9 8 10 4
出力例 2
63
入力例 3
6 2
1 4 5 6 11 15
12 5 9 8 10 4
出力例 3
35
入力例 4
6 5
1 4 5 6 11 15
12 5 9 8 10 4
出力例 4
19
情報オリンピック日本委員会
作 『第 20 回日本情報オリンピック JOI 2020/2021 二次予選競技課題』

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;
#define rep(i,n) for(ll i=0;i<n;i++)
#define all(A) A.begin(),A.end()


void solve(){
    ll N,K;
    cin>>N>>K;
    vector<ll> A(N),B(N);
    rep(i,N)cin>>A[i];
    rep(i,N)cin>>B[i];
    ll L=0,R=1e18;
    while(R-L>1){
        ll M=(R+L)/2;
        ll cnt=0;
        ll z=0;
        for(int i=N-1;i>=0;i--){
            if(M<=A[i]){
                cnt=K+10;
                break;
            }    
            ll D=(M-A[i]);
            ll Z=max(0ll,B[i]-z);
            ll nc=(Z+D-1)/D;
            cnt+=nc;
            z=nc*D-Z;
            while(i>0&&B[i-1]<=z){
                z-=B[i-1];
                i--;
            }
        }
        (K>=cnt?R:L)=M;
    }
    cout<<R<<endl;
}

int main(){
    
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T=1;
    while(T--)
    solve();
}
accuracy: 1
time_ms: 40
memory_kb: 4668
final_rank: 2

code_snippet: #line 1 "a.cpp"
#define PROBLEM ""
#line 2 "/home/kuhaku/home/github/algo/lib/template/template.hpp"
#pragma GCC target("sse4.2,avx2,bmi2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
template <class T, class U>
constexpr bool chmax(T &a, const U &b) {
    return a < (T)b ? a = (T)b, true : false;
}
template <class T, class U>
constexpr bool chmin(T &a, const U &b) {
    return (T)b < a ? a = (T)b, true : false;
}
constexpr std::int64_t INF = 1000000000000000003;
constexpr int Inf = 1000000003;
constexpr double EPS = 1e-7;
constexpr double PI = M_PI;
#line 3 "/home/kuhaku/home/github/algo/lib/template/macro.hpp"
#define FOR(i, m, n) for (int i = (m); i < int(n); ++i)
#define FORR(i, m, n) for (int i = (m)-1; i >= int(n); --i)
#define FORL(i, m, n) for (int64_t i = (m); i < int64_t(n); ++i)
#define rep(i, n) FOR (i, 0, n)
#define repn(i, n) FOR (i, 1, n + 1)
#define repr(i, n) FORR (i, n, 0)
#define repnr(i, n) FORR (i, n + 1, 1)
#define all(s) (s).begin(), (s).end()
#line 3 "/home/kuhaku/home/github/algo/lib/template/sonic.hpp"
struct Sonic {
    Sonic() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(20);
    }

    constexpr void operator()() const {}
} sonic;
#line 5 "/home/kuhaku/home/github/algo/lib/template/atcoder.hpp"
using namespace std;
using ll = std::int64_t;
using ld = long double;
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
    return is >> p.first >> p.second;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (T &i : v) is >> i;
    return is;
}
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
    return os << '(' << p.first << ',' << p.second << ')';
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    for (auto it = v.begin(); it != v.end(); ++it) {
        os << (it == v.begin() ? "" : " ") << *it;
    }
    return os;
}
template <class Head, class... Tail>
void co(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cout << head << '\n';
    else std::cout << head << ' ', co(std::forward<Tail>(tail)...);
}
template <class Head, class... Tail>
void ce(Head &&head, Tail &&...tail) {
    if constexpr (sizeof...(tail) == 0) std::cerr << head << '\n';
    else std::cerr << head << ' ', ce(std::forward<Tail>(tail)...);
}
template <typename T, typename... Args>
auto make_vector(T x, int arg, Args... args) {
    if constexpr (sizeof...(args) == 0) return std::vector<T>(arg, x);
    else return std::vector(arg, make_vector<T>(x, args...));
}
void Yes(bool is_correct = true) {
    std::cout << (is_correct ? "Yes" : "No") << '\n';
}
void No(bool is_not_correct = true) {
    Yes(!is_not_correct);
}
void YES(bool is_correct = true) {
    std::cout << (is_correct ? "YES" : "NO") << '\n';
}
void NO(bool is_not_correct = true) {
    YES(!is_not_correct);
}
void Takahashi(bool is_correct = true) {
    std::cout << (is_correct ? "Takahashi" : "Aoki") << '\n';
}
void Aoki(bool is_not_correct = true) {
    Takahashi(!is_not_correct);
}
#line 3 "a.cpp"

int main(void) {
    int n, k;
    cin >> n >> k;
    vector<int> a(n), b(n);
    cin >> a >> b;

    ll l = a.back(), r = INF;
    while (r - l > 1) {
        ll m = (l + r) / 2;
        ll s = 0, re = 0;
        repr (i, n) {
            if (re >= b[i]) {
                re -= b[i];
                continue;
            }
            ll x = (b[i] - re - 1) / (m - a[i]) + 1;
            s += x;
            re = x * (m - a[i]) - (b[i] - re);
        }
        if (s <= k)
            r = m;
        else
            l = m;
    }
    co(r);

    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3876
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
    int N, K;
    cin >> N >> K;
    vector<long long> A(N), B(N);
    for (int i = 0; i < N; ++i) cin >> A[N-i-1];
    for (int i = 0; i < N; ++i) cin >> B[N-i-1];

    auto judge = [&](long long x) -> bool {
        long long sum = 0, amari = 0;
        for (int i = 0; i < N; ++i) {
            if (amari >= B[i]) {
                amari -= B[i];
                continue;
            }
            long long work = B[i] - amari;
            long long each = x - A[i];
            if (each <= 0) return false;
            long long num = (work + each - 1) / each;
            sum += num;
            amari = each * num - work;
        }
        return sum <= K;
    };

    long long left = 0, right = 1LL<<60;
    while (right - left > 1) {
        long long x = (left + right) / 2;
        if (judge(x)) right = x;
        else left = x;
    }
    cout << right << endl;
}
accuracy: 1
time_ms: 70
memory_kb: 4676
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long int ll;

int main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int n; cin >> n;
	ll K; cin >> K;
	vector<ll> a(n),b(n);
	for(int i=0;i<n;i++){
		cin >> a[i];
	}
	for(int i=0;i<n;i++){
		cin >> b[i];
	}
	ll l=0,r=1e17;
	while(r-l>1){
		ll mid=(l+r)/2;
		if(a.back()>mid){
			l=mid;
			continue;
		}
		ll cnt=0;
		ll ty=0;
		vector<ll> bb=b;
		for(int i=n-1;i>=0;i--){
			if(bb[i]<=ty){
				ty-=bb[i];
				continue;
			}
			else{
				bb[i]-=ty;
				ty=0;
			}
			if(mid-a[i]==0){
				cnt=1e18;
				break;
			}
			ll num=(bb[i]+(mid-a[i]-1))/(mid-a[i]);
			cnt+=num;
			ty=num*(mid-a[i])-bb[i];
		}
		if(cnt<=K){
			r=mid;
		}
		else{
			l=mid;
		}
	}
	cout << r << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 5472
final_rank: 5

code_snippet: #include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <queue>
#include <string>
#include <random>
#include <array>
#include <climits>
#include <map>
#include <cassert>
#include <stack>
#include <iomanip>
#include <cfloat>
#include <fstream>


int main() {
	int n, k; std::cin >> n >> k;
	std::vector<int> facility(n);
	for (auto& a : facility) {
		std::cin >> a;
	}
	std::vector<int> check_list(n);
	for (auto& b : check_list) {
		std::cin >> b;
	}
	std::reverse(facility.begin(), facility.end());
	std::reverse(check_list.begin(), check_list.end());
	long long int min = facility[0] + 1;
	long long int max = LLONG_MAX >> 1;
	while (min < max) {
		const auto mid = (min + max) >> 1;
		int rest = k;
		long long int time{ mid - facility[0]};
		for (auto i = 0; i < n && 0 < rest; ++i) {
			auto check = check_list[i];
			if (check > time) {
				check -= time;
				--rest;
				const auto free_time = mid - facility[i];
				rest -= check / free_time;
				check %= free_time;
				if (check != 0) time = mid - facility[i];
				else time = (i + 1 < n) ? mid - facility[i + 1] : mid;
			}
			time -= check;
		}
		if (rest <= 0) {
			min = mid + 1;
		}
		else {
			max = mid;
		}
	}
	std::cout << max << '\n';
}
accuracy: 1
time_ms: 70
memory_kb: 3896
final_rank: 3

code_snippet: #include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <queue>
#include <string>
#include <random>
#include <array>
#include <climits>
#include <map>
#include <cassert>
#include <stack>
#include <iomanip>
#include <cfloat>
#include <fstream>


int main() {
	int n, k; std::cin >> n >> k;
	std::vector<int> facility(n);
	for (auto& a : facility) {
		std::cin >> a;
	}
	std::vector<int> check_list(n);
	for (auto& b : check_list) {
		std::cin >> b;
	}
	std::reverse(facility.begin(), facility.end());
	std::reverse(check_list.begin(), check_list.end());
	long long int min = facility[0] + 1;
	long long int max = LLONG_MAX >> 1;
	while (min < max) {
		const auto mid = (min + max) >> 1;
		int rest = k;
		long long int time{ mid - facility[0]};
		for (auto i = 0; i < n && 0 < rest; ++i) {
			auto check = check_list[i];
			if (check > time) {
				check -= time;
				--rest;
				const auto free_time = mid - facility[i];
				rest -= check / free_time;
				check %= free_time;
				time = mid - facility[i];
			}
			time -= check;
		}
		if (rest <= 0) {
			min = mid + 1;
		}
		else {
			max = mid;
		}
	}
	std::cout << max << '\n';
}
accuracy: 0.43333333333333335
time_ms: 70
memory_kb: 3900
final_rank: 8

code_snippet: #include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <queue>
#include <string>
#include <random>
#include <array>
#include <climits>
#include <map>
#include <cassert>
#include <stack>
#include <iomanip>
#include <cfloat>



int main() {
	int n, k; std::cin >> n >> k;
	std::vector<int> facility(n);
	for (auto& a : facility) {
		std::cin >> a;
	}
	std::vector<int> check_list(n);
	for (auto& b : check_list) {
		std::cin >> b;
	}
	long long int min = (*std::max_element(facility.begin(), facility.end())) + 1;
	long long int max = LLONG_MAX >> 1;
	while (min < max) {
		const auto mid = (min + max) >> 1;
		int rest = k;
		long long int time{ 0 };
		for (auto i = 0; i < n && 0 <= rest; ++i) {
			auto check = check_list[i];
			if (time + check + facility[i] > mid) {
				check -= mid - time - facility[i];
				--rest;
				time = 0;
				const int free_time = mid - facility[i];
				rest -= check / free_time;
				check %= free_time;
			}
			time += check;
		}
		if (rest < 0 || (rest == 0 && time > 0)) {
			min = mid + 1;
		}
		else {
			max = mid;
		}
	}
	std::cout << max << '\n';
}
accuracy: 0.05555555555555555
time_ms: 40
memory_kb: 3896
final_rank: 9

code_snippet: #include <bits/stdc++.h>
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define drep(i,j,n) for(int i=0;i<(int)(n-1);i++)for(int j=i+1;j<(int)(n);j++)
#define trep(i,j,k,n) for(int i=0;i<(int)(n-2);i++)for(int j=i+1;j<(int)(n-1);j++)for(int k=j+1;k<(int)(n);k++)
#define codefor int test;scanf("%d",&test);while(test--)
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define yes(ans) if(ans)printf("yes\n");else printf("no\n")
#define Yes(ans) if(ans)printf("Yes\n");else printf("No\n")
#define YES(ans) if(ans)printf("YES\n");else printf("NO\n")
#define popcount(v) __builtin_popcountll(v)
#define vector2d(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define vector3d(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
using namespace std;
using ll = long long;
template<class T> using rpriority_queue = priority_queue<T, vector<T>, greater<T>>;
const int MOD=1000000007;
const int MOD2=998244353;
const int INF=1<<30;
const ll INF2=1LL<<60;
void scan(int& a){scanf("%d",&a);}
void scan(long long& a){scanf("%lld",&a);}
template<class T,class L>void scan(pair<T, L>& p){scan(p.first);scan(p.second);}
template<class T,class U,class V>void scan(tuple<T,U,V>& p){scan(get<0>(p));scan(get<1>(p));scan(get<2>(p));}
template<class T, size_t size> void scan(array<T, size>& a){ for(auto&& i : a) scan(i);}
template<class T> void scan(T& a){cin>>a;}
template<class T> void scan(vector<T>& vec){for(auto&& it:vec)scan(it);}
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){scan(head);in(tail...);}
void print(const int& a){printf("%d",a);}
void print(const long long& a){printf("%lld",a);}
void print(const double& a){printf("%.15lf",a);}
template<class T,class L>void print(const pair<T, L>& p){print(p.first);putchar(' ');print(p.second);}
template<class T> void print(const T& a){cout<<a;}
template<class T> void print(const vector<T>& vec){if(vec.empty())return;print(vec[0]);for(auto it=vec.begin();++it!= vec.end();){putchar(' ');print(*it);}}
void out(){putchar('\n');}
template<class T> void out(const T& t){print(t);putchar('\n');}
template <class Head, class... Tail> void out(const Head& head,const Tail&... tail){print(head);putchar(' ');out(tail...);}
template<class T> void dprint(const T& a){cerr<<a;}
template<class T> void dprint(const vector<T>& vec){if(vec.empty())return;cerr<<vec[0];for(auto it=vec.begin();++it!= vec.end();){cerr<<" "<<*it;}}
void debug(){cerr<<endl;}
template<class T> void debug(const T& t){dprint(t);cerr<<endl;}
template <class Head, class... Tail> void debug(const Head& head, const Tail&... tail){dprint(head);cerr<<" ";debug(tail...);}
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
ll modinv(ll a, ll m) {ll b = m, u = 1, v = 0;while (b) {ll t = a / b;a -= t * b; swap(a, b);u -= t * v; swap(u, v);}u %= m;if (u < 0) u += m;return u;}
ll updivide(ll a,ll b){return (a+b-1)/b;}
int msb(ll v){return 63-__builtin_clzll(v);}
template<class T> void chmax(T &a,const T b){if(b>a)a=b;}
template<class T> void chmin(T &a,const T b){if(b<a)a=b;}

int main(){
    LL(n,k);
    vector<ll> a(n),b(n);
    in(a,b);
    auto f=[&](ll mid,vector<ll> c){
        int i=0;
        ll nxt=0,v,cnt=k;
        while(i<n){
            if(i>=1)nxt-=a[i]-a[i-1];
            if(nxt<0)nxt=0;
            c[i]-=nxt;
            v=updivide(c[i],mid-a[i]);
            nxt=(mid-a[i])*v-c[i];
            cnt-=v;
            if(cnt<0)return false;
            i++;
        }
        return (i==n);
    };
    ll l=a.back()+1,r=INF2,mid;
    while(l<r){
        mid=(l+r)/2;
        if(f(mid,b))r=mid;
        else l=mid+1;
    }
    out(l);
}
accuracy: 1
time_ms: 80
memory_kb: 5624
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001



#define SIZE 100005

ll N,K;
ll A[SIZE],B[SIZE];

bool isOK(ll T){

	ll POWER = 0;
	ll rest = K;

	/*■なるべく左方に多くの余力を残す■*/

	for(ll i = N-1; i >= 0; i--){
		if(rest == 0){ //全員が移動済

			if(POWER < B[i]){

				return false;
			}
			POWER -= B[i];

		}else{ //新規に移動できる人あり

			ll b = 0;

			if(POWER >= B[i]){

				POWER -= B[i];
				continue;

			}else{ //余力不足

				b = B[i]-POWER;
				POWER = 0;
			}

			ll tmp = T-A[i]; //■人をA[i]に引っ張ってきた時の余力
			if(tmp <= 0){

				return false;
			}
			ll need = (b+(tmp-1))/tmp;

			if(need > rest){

				return false;

			}else{
				rest -= need;
				POWER = tmp*need-b;
			}
		}
	}

	return true;
}

int main(){

	scanf("%lld %lld",&N,&K);

	for(ll i = 0; i < N; i++){

		scanf("%lld",&A[i]);
	}
	for(ll i = 0; i < N; i++){

		scanf("%lld",&B[i]);
	}

	ll left = 0,right = 1e16,mid = (left+right)/2;
	ll ans = 1e16;

	while(left <= right){
		if(isOK(mid)){

			ans = mid;
			right = mid-1;
		}else{

			left = mid+1;
		}
		mid = (left+right)/2;
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 4776
final_rank: 4