unun···
想到了算出座位总和,每次相减好操作——使用前缀和维护总座位数
求前边有多少个桌子坐满了:二分出一个 i ,使得si小于等于sum(最大的小于座位总数的数)
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
const int N = 200010;
int n, m;
LL s[N];
//二分
int work(LL sum){
int l = 0, r = n+1;
while(l+1<r){
int mid = l+r>>1;
if(s[mid]<=sum) l = mid;
else r = mid;
}
return n-l;
}
int main(){
cin>>n>>m;
for(int i=1; i<=n; i++){
int x;
cin>>x;
s[i] = s[i-1] + x;
}
LL sum = 0;//餐厅中总人数
while(m--){
LL x;
cin>>x;
sum += x;
if(sum >= s[n]) sum = 0;
printf("%d\n",work(sum));
}
return 0;
}
数学推导出二分关系
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
int main()
{
LL n, k, M, D;
cin >> n >> k >> M >> D;
LL res = 0;
for (int d = 1; d <= D; d ++ )
{
LL y = (d - 1) * k + 1;
if (y > n) break;
LL x = min(M, n / y);
if (n / x >= y && n / x <= d * k)
res = max(res, d * x);
}
cout << res << endl;
return 0;
}