1 条题解

  • 0
    @ 2025-8-24 22:55:34

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar yuyc
    人傻常数大

    搬运于2025-08-24 22:55:34,当前版本为作者最后更新于2024-02-20 10:32:34,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题意

    NN 头奶牛围成一圈,第 ii 头奶牛有一个容量为 aia_i 的桶,初始时桶满,每一时刻,每头奶牛都会根据一个操作序列 ss 来将自己桶中的 11 升牛奶倒给自己左边或右边的奶牛(如果桶里有牛奶的话),传递完之后,大于桶的容量那部分牛奶将会溢出,问 MM 时刻后,所有的桶里一共还剩多少牛奶。

    解析

    如果 sis_iRsi+1s_{i+1}L,那么我们就将这两个操作方向对应的两头奶牛称为两头 “溢牛”,或一个 “溢牛对”。

    为什么这样称呼呢? 注意到每次操作,溢牛对内部的总奶量不变,因为左边的溢牛总是能给右边的溢牛倒 11 升牛奶,右边的溢牛也总是能给左边的溢牛倒 11 升牛奶,相当于是每次互相交换 11 升牛奶。

    这就意味着,只要有牛奶被传递给溢牛对,这部分牛奶必定溢出,因为溢牛对内部奶量总是满的,故对于每一个溢牛对,只需求出可能被传递给它左右边的奶量,分别对 mm 取最小值即可求出每个溢牛对溢出的奶量。

    其实就是求每个溢牛对左边连续的 R 所对应的奶牛的奶量和右边连续的 L 所对应的奶牛的奶量。

    代码

    尤其注意奶牛们围成一个圈。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 2e5 + 5;
    ll a[N],b[N];
    int main(){
       	ios::sync_with_stdio(false);
       	cin.tie(0);
    	ll n,m;
    	ll ans = 0,sum = 0;
    	cin>>n>>m;
    	string s;
    	cin>>s;
    	s = s[n - 1] + s;
    	for(int i=1;i<=n;i++){
    		cin>>a[i];
    		sum += a[i];	
    	}
    	for(int i=0;i<=n;i++){
    		if(s[i] == 'R' && s[i + 1] == 'L'){
    			ll l = 0,r = 0;
    			int lpos = i - 1 <= 0 ? i - 1 + n : i - 1,rpos = i + 2 > n ? i + 2 - n : i + 2;
    			while(s[lpos] == 'R'){
    				l += a[lpos];
    				lpos--;
    				if(lpos <= 0) lpos += n;
    			}
    			while(s[rpos] == 'L'){
    				r += a[rpos];
    				rpos++;
    				if(rpos > n) rpos -= n;
    			}
    //			cout<<l<<' '<<r<<'\n';
    			ans += min(m,l) + min(m,r);
    		}
    	}
    	cout<<sum - ans;
        return 0;
    }
    
    
    
    • 1

    信息

    ID
    9818
    时间
    2000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者