zoukankan      html  css  js  c++  java
  • bzoj5259: [Cerc2017]区间

    还是很强的一个题 ORZ肉丝哥哥

    对于两个相交区间,假如他们两个都是可行的,那么他们的交也可行,不然没可能两边都把它缺的补上

    那么对于答案区间,向右找到第一个可行区间右端点覆盖询问区间,就是最优的

    考虑扫描线,枚举右端点,对于当前还没有找到答案的询问,取左端点最大的去找答案

    问题在于怎么快速判断一个区间是否可行

    用max-min==R-L没有前途像我一样,要考虑其他性质

    令i,i+1属于区间则对区间贡献1,假如[l,r]可行,那么它的权值就是r-l

    那么开一棵线段树,表示每个位置到R的最大对数和+l,假如等于r说明是合法方案,求一下区间最大值和它的位置即可

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    
    #define lc (now<<1)
    #define rc (now<<1|1)
    #define mid (ql+qr)/2
    #define mx first
    #define pos second
    using namespace std;
    typedef pair<int,int> pp;
    const int _=1e2;
    const int maxn=1e5+_;
    const int fbin=(1<<17)+_;
    
    struct trnode{pp p;int la;}tr[2*fbin];
    void update(int now){tr[now].p=max(tr[lc].p,tr[rc].p);}
    void pushdown(int now)
    {
        if(tr[now].la!=0)
        {
            tr[lc].p.mx+=tr[now].la;tr[lc].la+=tr[now].la;
            tr[rc].p.mx+=tr[now].la;tr[rc].la+=tr[now].la;
            tr[now].la=0;
        }
    }
    void bt(int now,int ql,int qr)
    {
        tr[now].p.mx=qr;tr[now].p.pos=qr;
        if(ql!=qr)
        {
            bt(lc,ql,mid);
            bt(rc,mid+1,qr);
        }
    }
    void add(int now,int ql,int qr,int l,int r,int w)
    {
        if(ql==l&&qr==r){tr[now].p.mx++,tr[now].la++;return ;}
        pushdown(now);
             if(r<=mid)  add(lc,ql,mid,l,r,w);
        else if(mid+1<=l)add(rc,mid+1,qr,l,r,w);
        else add(lc,ql,mid,l,mid,w),add(rc,mid+1,qr,mid+1,r,w);
        update(now);
    }
    pp findmax(int now,int ql,int qr,int l,int r)
    {
        if(ql==l&&qr==r)return tr[now].p;
        pushdown(now);
             if(r<=mid)  return findmax(lc,ql,mid,l,r);
        else if(mid+1<=l)return findmax(rc,mid+1,qr,l,r);
        else return max(findmax(lc,ql,mid,l,mid),findmax(rc,mid+1,qr,mid+1,r));
    }
    
    int n,a[maxn],b[maxn];
    struct query{int l,r,id;}q[maxn];int Q; pp as[maxn];
    bool cmp(query q1,query q2){return q1.r<q2.r;}
    struct cmq{bool operator()(query q1,query q2){return q1.l<q2.l;}};
    priority_queue<query,vector<query>,cmq>p;
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]),b[a[i]]=i;
        
        scanf("%d",&Q);
        for(int i=1;i<=Q;i++)
            scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
        sort(q+1,q+Q+1,cmp);
        
        int tp=1; bt(1,1,n);
        int x;query tq;pp tt;
        for(int i=1;i<=n;i++)
        {
            if(a[i]!=1)
            {
                x=b[a[i]-1];
                if(x<i)add(1,1,n,1,x,i);
            }
            if(a[i]!=n)
            {
                x=b[a[i]+1];
                if(x<i)add(1,1,n,1,x,i);
            }
            
            while(tp<=n&&q[tp].r==i)p.push(q[tp]),tp++;
            while(!p.empty())
            {
                tq=p.top();
                tt=findmax(1,1,n,1,tq.l);
                if(tt.first==i)
                {
                    as[tq.id]=make_pair(tt.pos,i);
                    p.pop();
                }
                else break;
            }
        }
        
        for(int i=1;i<=Q;i++)printf("%d %d
    ",as[i].mx,as[i].pos);
        
        return 0;
    }
  • 相关阅读:
    js中面向对象的写法
    js中防止全局变量被污染的方法
    移动端的头部标签和meta
    励志
    UX是什么?
    HTTP
    Django RestFramework (DRF)
    Vue(一)
    Vue-基础
    Vue-es6基础语法
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10621362.html
Copyright © 2011-2022 走看看