• luogu 2564 [SCOI2009]生日礼物


    题目背景

    四川2009NOI省选

    题目描述

    小西有一条很长的彩带,彩带上挂着各式各样的彩珠。已知彩珠有N个,分为K种。简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置)。某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上。

    小布生日快到了,于是小西打算剪一段彩带送给小布。为了让礼物彩带足够漂亮,小西希望这一段彩带中能包含所有种类的彩珠。同时,为了方便,小西希望这段彩带尽可能短,你能帮助小西计算这个最短的长度么?彩带的长度即为彩带开始位置到结束位置的位置差。

    输入格式

    第一行包含两个整数N, K,分别表示彩珠的总数以及种类数。接下来K行,每行第一个数为Ti,表示第i种彩珠的数目。接下来按升序给出Ti个非负整数,为这Ti个彩珠分别出现的位置。

    输出格式

    输出应包含一行,为最短彩带长度。

    输入输出样例

    输入 #1
    6 3
    1 5
    2 1 7
    3 1 3 8
    
    输出 #1
    3

    说明/提示

    【样例说明】

    有多种方案可选,其中比较短的是1~5和5~8。后者长度为3最短。

    【数据规模】

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

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

    对于100%的数据,1≤N≤1000000,1≤K≤60,0≤珠子位置<231

    Ti=n

    分析

    挺水的,

    把所有的珠子按位置排序,用一个 long long 的变量存目前已经得到了那些颜色

    另外用一个vis数组存有哪些颜色,有多少个(用于维护队列)

    队列中保证至少有一种颜色只有一颗珠子

    当队首的颜色有重复时,就弹出队首;

    新位置的颜色不管重没重复都放入队尾,同时颜色的个数++;

    如果已经达到全部颜色,就用队首与队尾更新ans

    注意最好将ans的更新与i一一对应,不能漏掉第一次或最后一次更新

    代码

     1 /*************************
     2 User:Mandy.H.Y
     3 Language:c++
     4 Problem:luogu
     5 Algorithm:
     6 Date:2019.8.30
     7 *************************/
     8 #include<bits/stdc++.h>
     9 #define Max(x,y) ((x) > (y) ? (x) : (y))
    10 #define Min(x,y) ((x) < (y) ? (x) : (y))
    11 
    12 using namespace std;
    13 
    14 const int maxn =  1e6 + 5;
    15 //数据范围 
    16 int n,k,l,r,cnt,ans = 0;
    17 long long color = 0;
    18 int q[maxn],vis[70];
    19 
    20 struct Node{
    21     int c,pos;
    22     bool operator <(const Node &a)const {
    23         return pos < a.pos ;
    24     }
    25 }node[maxn];
    26 
    27 template<class T>inline void read(T &x){
    28     x = 0;bool flag = 0;char ch = getchar();
    29     while(! isdigit(ch)) flag |= ch == '-',ch = getchar();
    30     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
    31     if(flag) x = -x;
    32 }
    33 
    34 template<class T>void putch(const T x){
    35     if(x > 9) putch(x / 10);
    36     putchar(x % 10 | 48);
    37 }
    38 
    39 template<class T>void put(const T x){
    40     if(x < 0) putchar('-'),putch(-x);
    41     else putch(x);
    42 }
    43 
    44 void file(){
    45     freopen("2564.in","r",stdin);
    46     freopen("2564.out","w",stdout);
    47 }
    48 
    49 void readdata(){
    50     read(n);read(k);
    51     for(int i = 1;i <= k; ++ i){
    52         int t;read(t);
    53         for(int j = 1;j <= t; ++ j){
    54             int x;read(x);
    55             node[++cnt].c = i - 1;
    56             node[cnt].pos = x;
    57         }
    58     }
    59     
    60     sort(node + 1,node + cnt + 1);
    61 }
    62 
    63 void work(){
    64     
    65     long long maxcolor = (1LL << k) - 1;
    66     ans = node[n].pos;
    67     
    68     for(int i = 1;i <= n; ++ i){
    69 //        if(color == maxcolor) ans = min(ans,node[q[r-1]].pos - node[q[l]].pos);
    70         q[r++] = i;vis[node[i].c]++;
    71         color |= (1ll << (long long)node[i].c);
    72         while(l < r && vis[node[q[l]].c] >= 2) vis[node[q[l]].c]--,l++; 
    73         if(color == maxcolor) ans = min(ans,node[q[r-1]].pos - node[q[l]].pos);
    74     }
    75     
    76 //    if(color == maxcolor) ans = min(ans,node[q[r-1]].pos - node[q[l]].pos);
    77     //注意如果将这一句放在循环的第一句,最后一次更新l可能没有更新答案 
    78     //以后注意写代码时,更新变量后一定紧跟更新答案 
    79     
    80     put(ans);
    81 }
    82 
    83 int main(){
    84 //    file();
    85     readdata();
    86     work();
    87     return 0;
    88 }
    View Code
    非做顽石不可,哪管他敬仰暗唾
  • 相关阅读:
    OPEN
    C#保存CookieContainer到文件
    Winform使用CefSharp和HttpWebRequest如何保持会话Session
    HttpWebResponse 四种acceptencoding解析(gzip, deflate, br,identity)
    ASP.NET TextBox 当鼠标点击后清空默认提示文字
    SQL Server 取日期时间部分
    C# datatable group by分组
    入坑.net core(一)简介
    入坑.net core(二)新建一个.net core api
    《C++ Primer》【Chapter 2】
  • 原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11433637.html
Copyright © 2020-2023  润新知