2023-08-01力扣每日一题

链接:

2681. 英雄的力量

题意:

对于一个序列可以得到一个值max^2 * min,求一个数组的所有子序列数值和

解:

快速幂和慢速乘+暴力 TLE(2558 / 2584)

首先对于这个数组来说,求值只依靠序列的最大值和最小值,并且所有子序列都要求,所以我们先将数组排序

对于每次遍历到的数字nums[i]都有一个nums[i]^3加入到ans里(表示子集[i,i],子集[l,r]表示以L为最小值,R为最大值的子集)

同时我们还要计算[0,i],[1,i]......[i-1,i],我们可以发现子集[l,r]的值的和nums[r]^2 * nums[l] * 2^r-l-1,因为l和r之间有r-l-1个数字,每个数字都有选与不选两种状态且不影响子集[l,r]的值,那我们可以发现每当R右移1,它所需要乘上的每个nums[l]就要翻一倍,所以我们使用一个变量来累积他所需要乘的数值

例如nums[1],nums[2],nums[3]

对于nums[1]我们只需要求nums[1]^3

对于nums[2]需要nums[2]^3 + nums[2]^2 * nums[1] * 1

对于nums[3]需要nums[3]^3 + nums[3]^2 * nums[2] *1 +nums[3]^2 *nums[1] * 2

这个nums[3]除了nums[3]^3,剩下的nums[3]^2 * nums[2] *1 +nums[3]^2 *nums[1] * 2可以转化为(nums[3]^2)*(nums[2]+ 2* nums[1])

以此类推下一个就是(nums[4]^2)*(nums[3]+ 2* nums[2]+ 4* nums[1])

实际代码:

#include<bits/stdc++.h>
using namespace std;
constexpr static long long Mod=1E9+7;
long long msc(long long base,long long up)
{
    //cout<<base<<"up"<<up<<endl;
    long long ret=0;
    while(up)
    {
        if(up&1) ret+=base;
        base+=base;
        base%=Mod;ret%=Mod;
        up>>=1;
    }
    return ret;
}
long long msm(long long base,long long up)
{
    //cout<<base<<"msmup"<<up<<endl;
    long long ret=1;
    while(up)
    {
        if(up&1) ret*=base;
        base=msc(base,base);
        base%=Mod;ret%=Mod;
        up>>=1;
    }
    return ret;
}
int sumOfPower(vector<int>& nums)
{
    sort(nums.begin(),nums.end());
    long long ans=0,after=0;
    int lg=nums.size();
    for(int i=0;i<lg;i++)
    {
        ans+=msm(nums[i],3);
        ans+=msm(nums[i],2)*after;
        after*=2;
        after+=nums[i];
        after%=Mod;ans%=Mod;
    }
    return ans;
}
/*
int sumOfPower(vector<int>& nums)
{
    sort(nums.begin(),nums.end());
    long long ans=0;
    int lg=nums.size();
    for(int i=0;i<lg;i++)
    {
        for(int j=i;j<lg;j++)
        {
            //cout<<"i:"<<i<<" "<<"j:"<<j<<endl;
            if(i==j) ans+=msm(nums[i],3);
            else
            {
                ans+=msc(msc(msm(nums[j],2),nums[i]),msm(2,j-i-1));
            }
            ans%=Mod;
        }
    }
    return ans;
}*/
int main()
{
    vector<int> nums;int num;
    while(cin>>num)
        nums.push_back(num);
    int ans=sumOfPower(nums);
    cout<<ans<<endl;
    return 0;
}

限制:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 109
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值