• [SCOI2009]生日礼物 单调性尺取法


    题意:给你n个k种颜色的点,每个点都有坐标和颜色两个属性,选出一个长度尽量短的区间,使得每种颜色的点都在区间内出现。

    数据范围:

    对于50%的数据, N≤10000;

    对于80%的数据, N≤800000;

    对于100%的数据,1≤N≤1000000,1≤K≤60,0≤珠子位置<2^{31}

    --------------------------------------------------我是分割线-------------------------------------------------------

    题解:单调性尺取法的经典应用。先将点按照坐标排序,用两个变量lr来枚举区间,如果lr的区间不满足要求,r++,如果lr的区间满足要求,记录答案,l++。

    排序时间复杂度O(NlogN),尺取时间复杂度O(N),总时间复杂度O(NlogN).

    #include<bits/stdc++.h>
    
    #define ll long long
    #define mp make_pair
    #define rep(i, a, b) for(int i = (a); i <= (b); i++)
    #define per(i, a, b) for(int i = (a); i >= (b); i--)
    
    using namespace std;
    
    typedef pair<int, int> pii;
    typedef double db;
    const int N = 1e6 + 50;
    struct node { int x, id; } a[N]; 
    int n, k, h, vis[N], q[N], u, ans = 1e9, cnt; 
    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<<3)+(x<<1)+(ch^48); ch = getchar();}
        return x*f;
    }
    bool mycmp(node a, node b){ return a.x < b.x; }
    void insert(int x) { if(vis[x] == 0) cnt++; vis[x]++; }
    void remove(int x) { if(vis[x] == 1) cnt--; vis[x]--; }
    void init(){
        n = read(); k = read();
        rep(i, 1, k){
            int t = read();
            rep(j, 1, t) a[++h].x = read(), a[h].id = i;
        }
        sort(a+1, a+n+1, mycmp);
    }
    void work(){
        int l = 1, r = 1;
        while(r <= n){
            insert(a[r].id);
            while(true) {
                remove(a[l].id); 
                if(cnt == k) l++;
                else { insert(a[l].id); break;}
            }
            if(cnt == k) ans = min(ans, a[r].x - a[l].x);
            r++;
        }
        printf("%d
    ", ans);
    }
    int main(){
        init();
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    马士兵讲jsp项目--BBS项目分析笔记
    ubuntu 14.04中安装phpmyadmin即mysql图形管理界面
    Xman冬令营writeup
    python--gevent协程及协程概念
    python--multiprocessing多进程总结
    python--threading多线程总结
    浅析Java中print、printf、println的区别
    内存泄漏与内存溢出
    Java中==和equals的区别,equals和hashCode的区别
    vue五十七:电影院售票项目案例之使用swiper实现轮播功能
  • 原文地址:https://www.cnblogs.com/smilke/p/11580240.html
Copyright © 2020-2023  润新知