zoukankan      html  css  js  c++  java
  • 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
    ",ans);
        return 0;
    }
  • 相关阅读:
    Java静态方法中使用注入类
    Java FTP辅助类
    Java SFTP辅助类
    MyBatis学习总结——批量查询
    MyBatis学习总结—实现关联表查询
    Redis集群搭建与简单使用
    SQL管理工具
    MySQL锁机制
    MySQL权限管理
    yii框架下使用redis
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7529938.html
Copyright © 2011-2022 走看看