Educational Codeforces Round 143 (Rated for Div. 2)C. Tea Tasting(前缀和+二分、贡献枚举)
C. Tea Tasting
思路
这里枚举有三种思路
然后经过考虑3是最可行的,然后接着考虑如何计算贡献
这里在实现的时候用了一个差分数组,因为我们需要记录第i个茶师它喝了多少个\(b_i\)以及不满\(b_i\)的用\(c_i\)记录,最后计算一下答案即可。
#include <bits/stdc++.h>
#define int long long
#define rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define fep(i, a, b) for(int i = (a); i >= (b); --i)
#define _for(i, a, b) for(int i=(a); i<(b); ++i)
#define pii pair<int, int>
#define pdd pair<double,double>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back
#define vi vector<int>
using namespace std;
const int maxn = 2e5 + 10;
int a[maxn],b[maxn],c[maxn],cf[maxn],s[maxn];
int n;
bool check(int l, int r){
if(s[r]-s[l-1]>a[l]) return true;
return false;
}
void solve() {
cin>>n;
rep(i,1,n+1){
s[i]=c[i]=cf[i]=0;
}
rep(i,1,n){
cin>>a[i];
}
rep(i,1,n){
cin>>b[i];
s[i]=s[i-1]+b[i];
}
rep(i,1,n){
int l=i,r=n;
while(l<r){
int mid=(l+r)>>1;
if(check(i,mid)) r=mid;
else l=mid+1;
}
if(check(i,l)){
cf[i]+=1;
cf[l]-=1;
c[l]+=a[i]-s[l-1]+s[i-1];
}else{
cf[i]+=1;
}
}
rep(i,1,n){
cf[i]+=cf[i-1];
}
//计算答案
vi ans(n+1);
rep(i,1,n){
ans[i]=cf[i]*b[i]+c[i];
}
rep(i,1,n){
cout<<ans[i]<<' ';
}
cout<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
// freopen("C:\\Users\\24283\\CLionProjects\\untitled2\\1.in", "r", stdin);
int _;
cin >> _;
while (_--)
solve();
return 0;
}