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();}
    
  • 相关阅读:
    重学计算机组成原理(七)- 程序无法同时在Linux和Windows下运行?
    学习ConcurrentHashMap并发写机制
    Unsafe中CAS的实现
    LinkedHashMap源码解读
    Hashset源码分析
    复盘MySQL分页查询优化方案
    Java面试必问之Hashmap底层实现原理(JDK1.8)
    Java面试必问之Hashmap底层实现原理(JDK1.7)
    Docker实战之Kafka集群
    Docker实战之Zookeeper集群
  • 原文地址:https://www.cnblogs.com/nanfeng-blog/p/15085906.html
Copyright © 2011-2022 走看看