• Problem C: 文体双花 解题报告


    Problem C: 文体双花


    被A穿的题,我这个屑只拿了20...

    意识到这个题简单的时候考试已经快结束了,那边又各种吵,不过下午改题的情况来看,我可能码力还有点问题...

    据神O所说,出这个题的时候没想到这个解法,然后考试的时候想到了...于是就成了真签到题


    考虑到连续段的表示可以为(r-l=mx-mi),然后很显然可以dp一下就是(dp_i)代表前(i)的贡献然后枚举(j)转移,考虑用线段树优化这个转移即可。

    具体的(rle mx+l-mi),然后在线段树上移动指针,维护右边的最小值和最小值贡献。

    (mx)(mi)的贡献在外面用单调栈维护一下就可以了。

    还是要注意一下细节的


    Code

    #include <cstdio>
    const int mod=1e9+7;
    const int N=1e5+10;
    #define add(a,b) (a+b>=mod?a+b-mod:a+b)
    #define ls id<<1
    #define rs id<<1|1
    struct beecute
    {
        int bee,sum;
        beecute friend operator +(beecute a,beecute b)
        {
            if(a.bee>b.bee) return b;
            if(a.bee==b.bee) a.sum=add(a.sum,b.sum);
            return a;
        }
    }bee[N<<2];
    int tag[N<<2],n,s0[N],s1[N],p[N],tot0,tot1;
    void build(int id,int l,int r)
    {
        int mid=l+r>>1;
        if(l^r) build(ls,l,mid),build(rs,mid+1,r),bee[id]=bee[ls]+bee[rs];
        else bee[id].bee=l,bee[id].sum=l==1;
    }
    void pushdown(int id)
    {
        if(tag[id])
        {
            bee[ls].bee+=tag[id],bee[rs].bee+=tag[id];
            tag[ls]+=tag[id],tag[rs]+=tag[id];
            tag[id]=0;
        }
    }
    void modi(int id,int L,int R,int l,int r,int d)
    {
        if(l==L&&r==R)
        {
            bee[id].bee+=d,tag[id]+=d;
            return;
        }
        pushdown(id);
        int Mid=L+R>>1;
        if(r<=Mid) modi(ls,L,Mid,l,r,d);
        else if(l>Mid) modi(rs,Mid+1,R,l,r,d);
        else modi(ls,L,Mid,l,Mid,d),modi(rs,Mid+1,R,Mid+1,r,d);
        bee[id]=bee[ls]+bee[rs];
    }
    void ins(int id,int l,int r,int p,int d)
    {
        if(l==r) {bee[id].sum=d;return;}
        pushdown(id);
        int mid=l+r>>1;
        if(p<=mid) ins(ls,l,mid,p,d);
        else ins(rs,mid+1,r,p,d);
        bee[id]=bee[ls]+bee[rs];
    }
    beecute query(int id,int l,int r,int p)
    {
        if(r==p) return bee[id];
        pushdown(id);
        int mid=l+r>>1;
        if(p<=mid) return query(ls,l,mid,p);
        else return bee[ls]+query(rs,mid+1,r,p);
    }
    int main()
    {
        scanf("%d",&n);
        build(1,1,n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",p+i);
            while(tot0&&p[s0[tot0]]<p[i])
            {
                modi(1,1,n,s0[tot0-1]+1,s0[tot0],p[i]-p[s0[tot0]]);
                --tot0;
            }
            s0[++tot0]=i;
            while(tot1&&p[s1[tot1]]>p[i])
            {
                modi(1,1,n,s1[tot1-1]+1,s1[tot1],p[s1[tot1]]-p[i]);
                --tot1;
            }
            s1[++tot1]=i;
            if(i<n) ins(1,1,n,i+1,query(1,1,n,i).sum);
        }
        printf("%d
    ",query(1,1,n,n).sum);
        return 0;
    }
    

    2019.1.18

  • 相关阅读:
    QT中PRO文件写法的详细介绍,很有用,很重要!
    What is the difference between authorized_key and known_host file for SSH
    SHELL DATE 命令详解
    Sample program to use PC/SC API.
    如何让用户关闭客户端IE时,触发Session_End事件
    Sql Create Function简单例子
    Css2.0实现圆角边框
    运算符重载的一个例子
    HTML获取URL传递的参数
    C#中自定义属性的例子
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10289337.html
Copyright © 2020-2023  润新知