• 洛谷P2564 [SCOI2009]生日礼物


    题意

    传送门

    分析

    一道单调队列的应用

    (其实有点不像是单调队列)

    大概就是先按照坐标轴排序,依次处理

    维护一个队列保存当前在队列中的每个球(记录其下标)

    然后对于每一个区间一定有右端点和一个左端点

    枚举右端点,左端点单调队列维护,可以求得最右的左端点的下标

    然后维护过程就是每次看当前这个颜色的(cnt)数组是否(>1),如果是,那么就可以不要这个点,这个点出队,如果不是,那么保留

    代码

    #include<bits/stdc++.h>
    using namespace std;
    template <typename T>
    inline void read(T &x){
    	x=0;char ch=getchar();bool f=false;
    	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	x=f?-x:x;
    	return ;
    }
    template <typename T>
    inline void write(T x){
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10^48);
    	return ;
    }
    const int N=1000005;
    int n,k,op,idx,cnt[N],now,ans=0x3f3f3f3f,hh,tt=-1,que[N]; 
    struct node{int x,id;}a[N];
    inline bool cmp(node x,node y){return x.x<y.x;}
    int main(){
    	read(n),read(k);
    	for(int i=1;i<=k;i++){
    		read(op);
    		for(int j=1;j<=op;j++){
    			read(a[++idx].x);
    			a[idx].id=i;
    		}
    	}
    	sort(a+1,a+idx+1,cmp);
    	for(int i=1;i<=n;i++){
    		if(cnt[a[i].id]==0) now++;
    		cnt[a[i].id]++;
    		que[++tt]=i;
    		while(hh<=tt&&cnt[a[que[hh]].id]>1) cnt[a[que[hh++]].id]--;
    		if(now==k) ans=min(ans,a[i].x-a[que[hh]].x);
    	}
    	write(ans);
    	return 0;
    }
    
    
  • 相关阅读:
    python小白-day9 数据库操作与Paramiko模块
    python小白-day8 线程、进程、协程
    python小白-day8 socketserver模块
    python小白-day7 socket初识
    python小白-day7 面向对象高级部分
    python小白-day6 xml处理模块
    python小白-day6 ConfigParser模块
    2020软件定义网络实验二
    软件工程实践第一次个人作业
    2020软件定义网络实验一
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14124934.html
Copyright © 2020-2023  润新知