uoj#213. UNR #1争夺圣杯

Posted ccz181078

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uoj#213. UNR #1争夺圣杯相关的知识,希望对你有一定的参考价值。

http://uoj.ac/problem/209

单调栈求出每个位置x左边第一个大于它的位置L[x]和右第一个不小于它的位置R[x],于是矩形L[x]<=l<=x<=r<=R[x]内的点(l,r)对应的区间[l,r]的最值为x位置的值,这个矩形内的点只对答案数组的二阶差分的四个位置有影响,可以全部统计后再求两次前缀和得到答案。

#include<bits/stdc++.h>
typedef long long i64;
const int N=1e6+7,P=998244353;
char ib[N*13],*ip=ib;
int _(){
    int x=0;
    while(*ip<48)++ip;
    while(*ip>47)x=x*10+*ip++-48;
    return x;
}
int n,a[N],ss[N],ls[N],rs[N],sp=0;
i64 s[N];
int main(){
    fread(ib,1,sizeof(ib),stdin);
    n=_();
    for(int i=1;i<=n;++i)a[i]=_();
    a[0]=a[n+1]=0x7fffffff;
    for(int i=1;i<=n+1;++i){
        while(sp&&a[ss[sp]]<a[i])rs[ss[sp--]]=i-1;
        ss[++sp]=i;
    }
    sp=0;
    for(int i=n;i>=0;--i){
        while(sp&&a[ss[sp]]<=a[i])ls[ss[sp--]]=i+1;
        ss[++sp]=i;
    }
    for(int i=1;i<=n;++i){
        int x=i-ls[i]+1,y=rs[i]-i+1;
        if(x>y)std::swap(x,y);
        s[0]+=a[i];
        s[x]-=a[i];
        s[y]-=a[i];
        s[x+y]+=a[i];
    }
    s[0]%=P;
    for(int i=1;i<n;++i)(s[i]+=s[i-1])%=P;
    for(int i=1;i<n;++i)(s[i]+=s[i-1])%=P;
    int ans=0;
    for(int i=0;i<n;++i)ans^=s[i]<0?s[i]+P:s[i];
    printf("%d\n",ans);
    return 0;
}

 

以上是关于uoj#213. UNR #1争夺圣杯的主要内容,如果未能解决你的问题,请参考以下文章

UOJ#308UNR#2UOJ拯救计划

UOJ #218. UNR #1火车管理

UOJ #390. UNR #3百鸽笼

[UOJ UNR#2 UOJ拯救计划]

uoj308 UNR #2UOJ拯救计划

Uoj308UNR #2UOJ拯救计划