zoukankan      html  css  js  c++  java
  • NOIP 模拟 $27; m 牛半仙的妹子序列$

    题解 (by;zjvarphi)

    明显一道极长上升子序列的题。

    直接线段树维护单调栈,最后单调栈求出可以贡献的序列,答案相加就行。

    Code
    #include<bits/stdc++.h>
    #define ri register signed
    #define p(i) ++i
    using namespace std;
    namespace IO{
        char buf[1<<21],*p1=buf,*p2=buf,OPUT[100];
        #define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(-1):*p1++;
        template<typename T>inline void read(T &x) {
            ri f=1;x=0;register char ch=gc();
            while(!isdigit(ch)) {if (ch=='-') f=0;ch=gc();}
            while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
            x=f?x:-x;
        }
        template<typename T>inline void print(T x,char t) {
            if (x<0) putchar('-'),x=-x;
            if (!x) return putchar('0'),(void)putchar(t);
            ri cnt(0);
            while(x) OPUT[p(cnt)]=x%10,x/=10;
            for (ri i(cnt);i;--i) putchar(OPUT[i]^48);
            return (void)putchar(t);
        }
    }
    using IO::read;using IO::print;
    namespace nanfeng{
        #define FI FILE *IN
        #define FO FILE *OUT
        template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
        template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
        static const int N=2e5+7,MOD=998244353;
        int pos[N],dp[N],v[N],st[N],wk[N],cnt,n,rmx,tmx,ans;
        inline int MD(int x) {return x>=MOD?x-MOD:x;}
        struct Seg{
            #define ls(x) (x<<1)
            #define rs(x) (x<<1|1)
            struct segmenttree{int sum,mx,tg;}T[N<<2];
            void build(int x,int l,int r) {
                if (l==r) return (void)(T[x].tg=1);
                int mid(l+r>>1);
                build(ls(x),l,mid);
                build(rs(x),mid+1,r);
            } 
            int calc(int x,int mx) {
                if (T[x].mx<=mx) return 0;
                if (T[x].tg) return dp[T[x].mx];
                if (T[rs(x)].mx<mx) return calc(ls(x),mx);
                return MD(T[x].sum+calc(rs(x),mx)); 
            }
            inline void up(int x) {
                T[x].mx=cmax(T[ls(x)].mx,T[rs(x)].mx);
                T[x].sum=calc(ls(x),T[rs(x)].mx);
            }
            void update(int x,int k,int p,int l,int r) {
                if (l==r) return (void)(T[x].mx=k);
                int mid(l+r>>1);
                if (p<=mid) update(ls(x),k,p,l,mid);
                else update(rs(x),k,p,mid+1,r);
                up(x);
            }
            int query(int x,int l,int r,int lt,int rt) {
                if (l<=lt&&rt<=r) return tmx=rmx,rmx=cmax(rmx,T[x].mx),calc(x,tmx);
                int mid(lt+rt>>1),res(0);
                if (r>mid) res+=query(rs(x),l,r,mid+1,rt);
                if (l<=mid) res+=query(ls(x),l,r,lt,mid);
                return MD(res);
            }
        }T;
        inline int main() {
            //FI=freopen("nanfeng.in","r",stdin);
            //FO=freopen("nanfeng.out","w",stdout);
            read(n);
            for (ri i(1);i<=n;p(i)) read(v[i]),pos[v[i]]=i;
            ri tp=0;
            for (ri i(1);i<=n;p(i)) {
                while(tp&&v[st[tp]]<v[i]) --tp;
                st[p(tp)]=i;
            }
            while(tp) wk[p(cnt)]=st[tp--];
            T.build(1,1,n);
            for (ri i(1);i<=n;p(i)) {
                ri cur(pos[i]);
                rmx=0;
                dp[i]=T.query(1,1,cur,1,n);
                if (!dp[i]) dp[i]=1;
                T.update(1,i,cur,1,n);
            }
            for (ri i(1);i<=cnt;p(i)) ans=MD(ans+dp[v[wk[i]]]);
            print(ans,'
    ');
            return 0;
        }
    }
    int main() {return nanfeng::main();}
    
  • 相关阅读:
    疫情信息爬取及可视化 app
    计算机组成与体系结构——校验码知识点
    计算机组成与体系结构——其他知识点(二)
    计算机组成与体系结构——其他知识点(一)
    计算机组成与体系结构——流水线相关知识点(常考计算)
    计算机组成与体系结构——数据的表示
    C语言经典试题--指针
    软件工程--个人课程总结
    学生信息管理系统--基于jsp技术和MySQL的简单增删改查
    计算最长英语单词链
  • 原文地址:https://www.cnblogs.com/nanfeng-blog/p/15085906.html
Copyright © 2011-2022 走看看