zoukankan      html  css  js  c++  java
  • P2564 [SCOI2009]生日礼物

    传送门

    看到最短容易想到二分答案,然后发现尺取法还更好搞

    动态维护左右端点 $l,r$,维护 $p[i]$ 表示颜色 $i$ 最后一次出现的位置,$cnt$ 维护当前有几种不同颜色

    随着 $l$ 增大,显然它的最小的 $r$ 是不降的,所以枚举 $l$,动态右移 $r$ ,维护 $p$ 并维护 $cnt$

    因为同种颜色位置不同所以不用离散化,否则要记得离散化

    复杂度 $O(n)$

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=2e6+7,INF=1e9+7;
    struct dat{
        int pos,col;
        inline bool operator < (const dat &tmp) const {
            return pos<tmp.pos;
        }
    }d[N];
    int n,m,p[N],ans=INF;
    int main()
    {
        n=read(),m=read();
        int tot=0,a;
        for(int i=1;i<=m;i++)
        {
            a=read();
            while(a--) d[++tot].pos=read(),d[tot].col=i;
        }
        sort(d+1,d+n+1);
        int l=1,r=0,cnt=0;
        while(l<=n)
        {
            while(cnt<m&&r<=n)//对于当前的l找到最近的r
            {
                r++;
                if(!p[d[r].col]) cnt++;//维护cnt
                p[d[r].col]=d[r].pos;//维护p
            }
            if(r>n) break;
            ans=min(ans,d[r].pos-d[l].pos);
            if(p[d[l].col]==d[l].pos) p[d[l].col]=0,cnt--;//如果当前颜色是最左边的颜色才要考虑更新
            l++;
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    uni app 零基础小白到项目实战
    uni-app 事件以及事件绑定
    uni-app 事件以及事件绑定
    uni-app 组件
    uni-app 组件
    uni-app 网络请求
    uni-app 网络请求
    uni-app 图片上传实战
    uni-app 图片上传实战
    uni-app下拉刷新加载刷新数据
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/10587562.html
Copyright © 2011-2022 走看看