巫师的总力量和

总力量定义为以下两个值的 乘积:
巫师中最弱的能力值
组中所有巫师的个人力量值之和

1. 单调栈+前缀和+前缀和

根据单调栈求得每一个值的辖域(当前值为最小值的最长数组范围)
接下来问题就转化成了求在辖域中包含当前值所有子数组的和
求和我们采用前缀和的方式

对于abcde,假设c为当前辖域最小值,则所有子数组和为presum[c/d/e]-presum[a/b/c-1]
presum[c/d/e]要分别列举三次求和,由左边个数决定,presum[a/b/c-1]要列举3次求和,由右边个数决定
为了快速求c/d/e的和,以及a/b/c的和,这里再次使用前缀和

class Solution {
public:
    int totalStrength(vector<int>& arr) {
        const int mod = 1e9+7;
        int n = arr.size();
        vector<int> monoStack; //单调栈
        vector<int> left(n), right(n);//左右边界
        for (int i = 0; i < n; i++) {//从左往右找左边更小值
            while (!monoStack.empty() && arr[i] <= arr[monoStack.back()]) {//把更大的值挤出来,相等的视为更大,区间计算的时候不影响
                monoStack.pop_back();
            }
            left[i] = monoStack.empty() ? -1: monoStack.back(); //左边界,左开
            monoStack.emplace_back(i);//放入坐标
        }
        monoStack.clear();
        for (int i = n - 1; i >= 0; i--) { //从右往左找右边更小值
            while (!monoStack.empty() && arr[i] < arr[monoStack.back()]) {
                monoStack.pop_back();
            }
            right[i] = monoStack.empty() ? n : monoStack.back(); //右边界,右开
            monoStack.emplace_back(i);
        }

        vector<long long> presum(n+1);
        vector<long long> sumsum(n+2);
        for(int i=0;i<n;i++){
            presum[i+1] = presum[i]+arr[i];//前缀和
            sumsum[i+2] = (sumsum[i+1]+presum[i+1])%mod;
        }
        long long res = 0;
        for(int i=0;i<n;i++){//遍历每一个数
            int r = right[i]-1;//这里是闭区间
            int l = left[i]+1;//这里是闭区间
            //presum[i]/presum[i+1]....presum[r] - presum[i-1]....presum[l]
            //左边个数为i-l+1,右边个数为r-i+1(包含本身)
            long long cur = ((sumsum[r+2]-sumsum[i+1])*(i-l+1) - (sumsum[i+1]-sumsum[l])*(r-i+1))%mod;
            res = (res+cur*arr[i])%mod;
        }
        return (res+mod)%mod;
    }
};

posted @   失控D大白兔  阅读(26)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
历史上的今天:
2022-05-19 LeetCode/零钱兑换
2022-05-19 LeetCode/完全平方数
点击右上角即可分享
微信分享提示