Luogu P4734 [BalticOI 2015]Hacker

Link
结论\(1\):能够选的电脑数为\(\lfloor\frac{n+1}2\rfloor\)
结论\(2\):若先手先选了\(x\),那么后手可以让先手最后选到的电脑的左端点为\([x-\lfloor\frac{n+1}2\rfloor,x]\)中的任意一个。这可以采用模仿策略做到。
那么我们单调队列维护即可。

#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
const int N=1000007;
int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
int a[N],f[N],q[N];
int main()
{
    int n=read(),m=(n+1)/2,ans=0;
    for(int i=1;i<=n;++i) a[i]=read();
    memcpy(a+n+1,a+1,n<<2);
    for(int i=1,s=0;i<=n+m-1;++i)
    {
	if(s+=a[i],i>m) s-=a[i-m];
	if(i>=m) f[i-m+1]=s;
    }
    memcpy(f+n+1,f+1,n<<2);
    for(int i=1,l=0,r=0;i<=n+m-1;++i)
    {
        while(l<=r&&q[l]<=i-m) ++l;
        while(l<=r&&f[q[r]]>=f[i]) --r;
	if(q[++r]=i,i>=m) ans=std::max(ans,f[q[l]]);
    }
    printf("%d",ans);
}
posted @ 2020-03-16 15:38  Shiina_Mashiro  阅读(133)  评论(0编辑  收藏  举报