[USACO14OPEN]Fair Photography【前缀和】

Pro

Luogu3105

Sol

先考虑不修改的情况,把0看成-1,(好像差分), s u m 为前缀和, l a s t s u m 头牛第一次出现的位置。

以下引自黄学长(@hzwer)

经典题。。。把0看成-1

如果不考虑修改那么用last[x]记录前缀和为x的第一个位置

然后扫一遍

修改的处理,设当前位置pos,前缀和为x,则pos-last[x],pos-last[x+2]…都能更新,取最优值

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

struct Node {
    int p , st;
    bool operator < (const Node &a) const {
        return a.p > p;
    }
}a[100001];
long long n , last[1000001] , now , ans;
char c;

long long min(long long b , long long c) {
    return b<c?b:c;
}

long long max(long long b , long long c) {
    return b>c?b:c;
}

int main()
{
    memset(last , 0x3f , sizeof(last));
    scanf("%lld",&n);
    for(int i=1;i<=n;++i)
    {
        scanf("%lld",&a[i].p);
        cin>>c;
        if(c=='W')
            a[i].st=-1;
        else
            a[i].st=1;
    }
    sort(a+1,a+n+1);
    now=n;
    last[now]=a[1].p;
    for(int i=2; i<=n; i++) {
        now += a[i-1].st;
        last[now] = min(last[now] , a[i].p);
    }
    for(int i=2*n; i; i--)
        last[i] = min(last[i] , last[i+2]);
    now = n;
    for(int i=1; i<=n; i++) {
    now += a[i].st;
        ans = max(ans , a[i].p-last[now]);  
    }
    printf("%lld",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43061009/article/details/82083714