做优化的网站电话简易购物网站前端模板
一种特殊的前缀方法:
通过前后两次前缀,可以求出目的区间值
例题1:
最大或值:2680. 最大或值 - 力扣(LeetCode)(贪心+前缀)
贪心可知只让一个数变化最后或值最大,所以通过前后缀求出区间数,使得变化所有区间数求出最大就行
class Solution {
public:long long maximumOr(vector<int>& nums, int k) {int n=nums.size();vector<long long>l(n+10,0);vector<long long>r(n+10,0);for(int i=1;i<=n;i++) l[i]=l[i-1] | nums[i-1];for(int i=n-1;i>=0;i--) r[i]=r[i+1] | nums[i];long long max1=0;for(int i=0;i<n;i++){long long current=(l[i] | r[i+1]) | ((long long)(nums[i]) << k);max1=max(current,max1);}return max1;}
};
例题2:
爱吃糖的小蓝:1.爱吃糖的小蓝 - 蓝桥云课 (前缀+二分)
先进行前后缀和计算,这样可以找到需要删除的中间糖果区间,然后在确定前区间的情况下二分优化找到后区间选择的糖果位置
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,h;
int a[1000010],pre[1000010],nex[1000010];
signed main()
{cin>>n>>h;for(int i=1; i<=n; i++) cin>>a[i];for(int i=1; i<=n; i++){pre[i]=pre[i-1]+a[i];}for(int i=n; i>=1; i--){nex[i]=nex[i+1]+a[i];}if(pre[n]<=h){cout<<pre[n]<<endl;return 0;}int ans=0;for(int i=0; i<=n; i++){if(pre[i]>h) break;int target=h-pre[i];int index=lower_bound(nex+i+1,nex+n+1,target,greater<int>())-nex; //第一个不大于target的元素位置(-next+1是不小于) greater需要反方向找 if(index>n){ans=max(ans,pre[i]);}else{ans=max(ans,pre[i]+nex[index]);}}cout<<ans<<endl;return 0;
}