Educational Codeforces Round 143 (Rated for Div. 2)C. Tea Tasting(前缀和+二分、贡献枚举)

C. Tea Tasting

思路

这里枚举有三种思路
ddade224bdd5d1f5173e12fa7546362.jpg
然后经过考虑3是最可行的,然后接着考虑如何计算贡献
8bfbaaa29472d7706a8bce09d06b9af.jpg
这里在实现的时候用了一个差分数组,因为我们需要记录第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;
}
posted @ 2024-03-03 17:04  cxy8  阅读(5)  评论(0编辑  收藏  举报