• [CERC2017]Intrinsic Interval(神仙+线段树)


    题目大意:给一个1-n的排列,有一堆询问区间,定义一个好的区间为它的值域区间长度等于它的区间长度,求包这个询问区间的最小好的区间。

    题解

    做法太神了,根本想不到。

    %%%i207m。

    结论:当一个区间中相邻的数的对数等于区间长度-1,那么这个区间是好的区间,证明:*%%%%……*%%¥。

    所以我们可以用扫描线对1-n扫一遍,用线段树维护i-now的相邻的数的对数,如果我们令a[i]+=i;那么当我们做到r时且a[l]=r,那么l到r是好区间。

    然后我们对于每个询问按照l从大到小做,如果找不到就break掉。

    代码

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #define N 100002
    using namespace std;
    int tr[N<<2],la[N<<2],mx[N<<2],nowma,ga,zuo,n,pos[N],m,ansl[N],ansr[N],a[N];
    inline int rd(){
        int x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    }
    struct Q{
        int l,r,id;
        bool operator <(const Q &b)const{return l<b.l;}
    };
    vector<Q>vec[N];
    priority_queue<Q>q;
    inline void pushdown(int cnt){
        tr[cnt<<1]+=la[cnt];tr[cnt<<1|1]+=la[cnt];
        la[cnt<<1]+=la[cnt];la[cnt<<1|1]+=la[cnt];
        la[cnt]=0;
    }
    inline void pushup(int cnt){
        tr[cnt]=tr[cnt<<1];mx[cnt]=mx[cnt<<1];
        if(tr[cnt<<1|1]==tr[cnt])mx[cnt]=max(mx[cnt],mx[cnt<<1|1]);
        else if(tr[cnt<<1|1]>tr[cnt])tr[cnt]=tr[cnt<<1|1],mx[cnt]=mx[cnt<<1|1]; 
    }
    void build(int cnt,int l,int r){
        if(l==r){tr[cnt]=l;mx[cnt]=l;return;}
        int mid=(l+r)>>1;
        build(cnt<<1,l,mid);build(cnt<<1|1,mid+1,r);
        pushup(cnt);
    }
    void upd(int cnt,int l,int r,int L,int R){
        if(l>=L&&r<=R){tr[cnt]++;la[cnt]++;return;}
        int mid=(l+r)>>1;
        if(la[cnt])pushdown(cnt);
        if(mid>=L)upd(cnt<<1,l,mid,L,R);
        if(mid<R)upd(cnt<<1|1,mid+1,r,L,R);
        pushup(cnt);
    }
    void query(int cnt,int l,int r,int L,int R){
        if(l>=L&&r<=R){
            if(tr[cnt]>=nowma){nowma=tr[cnt];zuo=mx[cnt];}
            return;
        }
        int mid=(l+r)>>1;
        if(la[cnt])pushdown(cnt);
        if(mid>=L)query(cnt<<1,l,mid,L,R);
        if(mid<R)query(cnt<<1|1,mid+1,r,L,R);
    }
    inline bool pd(Q a){
        int l=a.l,r=a.r,id=a.id;nowma=0;
        query(1,1,n,1,l);
       // cout<<nowma<<" __ "<<ga<<endl; 
        if(nowma==ga){
            ansl[id]=zuo;ansr[id]=ga;return 1;
        }
        return 0;
    }
    int main(){
        n=rd();
        build(1,1,n);
        for(int i=1;i<=n;++i)a[i]=rd(),pos[a[i]]=i;
        m=rd();
        for(int i=1;i<=m;++i){
            int l=rd();int r=rd();
            vec[r].push_back(Q{l,r,i});
        }
        for(int i=1;i<=n;++i){
            ga=i;
            if(a[i]>1&&pos[a[i]-1]<=i)upd(1,1,n,1,pos[a[i]-1]);
            if(a[i]<n&&pos[a[i]+1]<=i)upd(1,1,n,1,pos[a[i]+1]);
            for(int j=0;j<vec[i].size();++j)q.push(vec[i][j]);
            while(!q.empty()){if(pd(q.top()))q.pop();else break;}
        }
        for(int i=1;i<=m;++i)printf("%d %d
    ",ansl[i],ansr[i]);
        return 0;
    }
  • 相关阅读:
    mysql数据类型
    Hive Getting Started补充
    Hive安装
    HDFS High Availability Using the Quorum Journal Manager
    用DBContext (EF) 实现通用增删改查的REST方法
    Internet Explorer 10 administration IE10管理
    配置AD RMS及SharePoint 2013 IRM问题解决及相关资源
    SharePoint 2013 首页修改
    Status: Checked in and viewable by authorized users 出现在sharepoint 2013 home 页面
    添加AD RMS role时,提示密码不能被验证The password could not be validated
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/10180497.html
Copyright © 2020-2023  润新知