description:

有n个水果 每个水果有个喜爱度ai 求连续最大长度水果喜爱值之和大于0

solution:

首先想到一个双指针 但是无法保证指针的移动就是对于答案有利的
1.维护一个后缀max前缀和 判断当前r指针往下走 是否对答案有利 如果sum[l] 也就是l的前缀和< last[r] 也就是r位置的后缀位置max前缀和 就可以保证l~r位置是 >0的 符合条件 继续伸展 反之的话 直接跳过

2.二分 二分的话其实和双指针的思路类似 我们维护一个前缀和sum 正向维护一个ai保存当前最小的前缀和 即ai = min(a[i - 1],sum) 设定二分上界为i+1 下界为0 二分去找和当前前缀和相近的位置 判断上下界和sum的关系 保证之间的差为正数 即符合题意 取最大值就好

3.排序 排序是最好理解的 结构体维护前缀和值和当前位置pos 根据贪心的思想肯定是值为第一优先选择 其次为pos降序排列 维护一个当前最小的pos值 只有当前pos值 < 最小pos值mi时 才有机会更新答案 特别要注意的是 排序的时候 x = 0 & pos = 0 的状态也要考虑进去 这也属于答案中的一种状态

code:

代码按照思路顺序给出

#include <bits/stdc++.h>

using namespace std;


const int N = 2e6 + 50,INF = 0x3f3f3f3f;

int sum[N],last[N];

int main(){
    ios::sync_with_stdio(0);

    int n;

    cin >> n;

    memset(last,-INF,sizeof(last));

    for(int i = 1;i <= n;i ++){
        int x;
        cin >> x;
        sum[i] = sum[i - 1] + x;
    }

    for(int i = n;i >= 1;i --){
        last[i] = max(last[i + 1],sum[i]);
    }

    int l = 0,r = 1,res = 0;

    for(;l < n;l ++,r ++){
        if(sum[l] >= last[r]){
            continue;
        }

        while(sum[l] < last[r] && r <= n){
            ++ r;
        }
        -- r;
        res = max(res,r - l);
    }

    cout << res << '\n';
    return 0;
}
#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define ULL unsigned long long
#define mes(x, a) memset(x, a, sizeof(x));
#define sca(a) scanf("%d", &a)
#define lowbit(x) x&(-x)
#define mk make_pair
#define pb(x) push_back(x)
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define lson v << 1
#define rson v << 1 | 1
#define pii pair<int, int>

inline void read(int &x)
{
    x=0;
    int flag_read=1;
    char c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-')
            flag_read=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9')
    {
        x=(x<<3)+(x<<1)+c-'0';
        c=getchar();
    }
    x *= flag_read;
}

void out(int x){
    if(x > 9){
        out(x / 10);
    }
    putchar(x % 10 + '0');
}

const int N = 2e6 + 50;
#define LL long long

int a[N];

int main(){
    ios::sync_with_stdio(0);
    int n;

    cin >> n;

    int sum = 0;
    int res = 0;

    for(int i = 1;i <= n;i ++){
        int x;cin >> x;

        sum += x;
        a[i] = min(a[i - 1],sum);

        int l = 0,r = i + 1;

        while(l + 1 < r){
            int mid = l + r >> 1;
            if(a[mid] >= sum){
                l = mid;
            }else{
                r = mid;
            }
        }

        if(a[l] < sum){
            res = max(res,i - l);
        }else{
            res = max(res,i - r);
        }
    }

    cout << res << '\n';

    return 0;
}

排序

#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define ULL unsigned long long
#define mes(x, a) memset(x, a, sizeof(x));
#define sca(a) scanf("%d", &a)
#define lowbit(x) x&(-x)
#define mk make_pair
#define pb(x) push_back(x)
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define lson v << 1
#define rson v << 1 | 1
#define pii pair<int, int>

inline void read(int &x)
{
    x=0;
    int flag_read=1;
    char c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-')
            flag_read=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9')
    {
        x=(x<<3)+(x<<1)+c-'0';
        c=getchar();
    }
    x *= flag_read;
}

void out(int x){
    if(x > 9){
        out(x / 10);
    }
    putchar(x % 10 + '0');
}

const int N = 2e6 + 50;

struct node{
    int x;
    int pos;  
};

node a[N];

bool cmp(node a,node b){
    if(a.x != b.x){
        return a.x < b.x;
    }
    return a.pos > b.pos;
}

int main(){
    ios::sync_with_stdio(0);
    int n;

    cin >> n ;

    for(int i = 1;i <= n;i ++){
        int x;
        cin >> x;

        a[i].x = a[i - 1].x + x;
        a[i].pos = i;
    }

    sort(a ,a + 1 + n,cmp);

    int mi = 1 << 30,res = 0;

    for(int i = 0;i <= n;i ++){
        mi = min(mi,a[i].pos);
        if(mi < a[i].pos){
            res = max(res,a[i].pos - mi);
        }
    }

    cout << res << '\n';

    return 0;
}