luogu_P1638 逛画展

尺取法,先右挪右端点,可以了就挪左端点至不行,然后又挪右端点,一直一直一直这样子

#include<iostream>
#include<cstdio>

#define ri register int
#define u int

namespace opt {

    inline u in() {
        u x(0),f(1);
        char s(getchar());
        while(s<‘0‘||s>‘9‘) {
            if(s==‘-‘) f=-1;
            s=getchar();
        }
        while(s>=‘0‘&&s<=‘9‘) {
            x=(x<<1)+(x<<3)+s-‘0‘;
            s=getchar();
        }
        return x*f;
    }

}

using opt::in;

#define NN 1000005

namespace mainstay {

    u N,M,cnt,ans[3]={0x7fffffff},vt[NN],a[NN];

    inline void solve(){
        N=in(),M=in();
        for(ri i(1);i<=N;++i) a[i]=in();
        u l(1),r(0);
        while(1){
            if(l>=N||r>=N) break;
            if(!vt[a[r+1]]) ++cnt;
            ++vt[a[++r]];
            while(cnt==M){
                if(r-l+1<ans[0]){
                    ans[0]=r-l+1,ans[1]=l,ans[2]=r;
                }
                --vt[a[l++]];
                if(!vt[a[l-1]]) --cnt;
            }
        }
        std::cout<<ans[1]<<" "<<ans[2];
    }

}

int main() {

    //freopen("x.txt","r",stdin);
    std::ios::sync_with_stdio(false);
    mainstay::solve();

}

原文地址:https://www.cnblogs.com/ling-zhi/p/11828715.html

时间: 2024-10-09 09:08:59

luogu_P1638 逛画展的相关文章

逛画展

洛谷P1638 逛画展 很经典的一道类似有一个头,一个尾,然后头和尾移动,从前往后扫一遍的题,我以前做过一道类似的,很相似,不过我不记得了,唉,可惜.正解是枚举区间的左右端点,右端点不断移动直到正好框住k种,此时,(r-l)与(j-i)比较,更新l,r,最后i++,直到i==n. 我一开始也没想到这样枚举,我想的是枚举框的长度,这样从小到大枚举,每次扫一遍判断是否包含k个,A了4个点,剩下的都TLE了... #include<bits/stdc++.h> using namespace std

洛谷P1638 逛画展

P1638 逛画展 1 #include <bits/stdc++.h> 2 #define LL long long 3 #define For(i,j,k) for(int i=j;i<=k;i++) 4 using namespace std ; 5 6 const int N = 1000011 ; 7 int n,m,ansl,ansr,le,ri ; 8 int a[N],f[2011] ; // 9 10 inline int read() 11 { 12 int x =

【Luogu1638】逛画展

点此进入原题 算法:(有技巧的)模拟 题解: 这题可以不用真实的队列,只要用两个变量模拟一下就可以啦 也可以说是枚举的思想:这题很容易想到O(n^2)的枚举区间的算法,容易TLE.先找到第一个包含所有不同数字的区间[i,j],然后让i+1,同时枚举j找到另一个区间,然后取j-i的最小值就OK辣.判断不同的数字完全可以用桶解决 可能我的语文差了一点,具体看我的代码吧(好难表述啊QAQ) 代码: #include<cstdio> const int N=1000005,M=2017; int a[

P1638 逛画展(直尺法)

这道题是直尺法的模板题: #include<iostream> using namespace std; const int maxn = 1e6 + 5; const int M = 2e3 + 5; int n, m, a[maxn], vis[M]; int main(){ cin >> n >> m; for (int i = 0; i < n; ++i)cin >> a[i]; int st = 0, en = 0, num = 0, res

单调队列,单调栈相关

说起这个话题,应该很多人会有一种似有所悟,但又不敢确定的感觉. (我差不多就是那样) 没错,这正是因为其中“单调”一词的存在. 那么单调是什么? 学过函数的人都知道单调函数或者函数的单调性吧 其实直白一点说单调,就是一直增或一直减. eg:1,3,5,9就是一个单调增数列,数列中不存在后一个数比前一个数小的现象. 那么同样,在这里谈到的话题也有类似特点. (一)单调队列 其实就是一个符合单调性质的队列,但它同时具有单调的性质以及队列的性质. 使用频率不算高,但却占有至关重要的地位.它的作用很简单

Luogu P1083 借教室【二分答案/差分】By cellur925

题目描述 Description 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要 向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自然希望编程解决这个问题. 我们需要处理接下来n天的借教室信息,其中第i天学校有ri个教室可供租借.共有m份 订单,每份订单用三个正整数描述,分别为dj, sj, tj,表示某租借者需要从第sj天到第tj天租 借教室(包括第sj天和第tj天),每天需要租借dj个教室. 我们假定

单调队列/单调栈入门详解+题目推荐

以前一直以为这两个是很高级的东西,这段时间用到了才开始学,发现实际上非常简单 下面我们以单调队列为例进行讲解,单调栈自行类比 顾名思义 单调队列这个名字就指明了它的性质--单调性 我们来看一道例题--滑动窗口 题面在此不再赘述,大意就是有一个长度为\(n\)的数列,一个长度为\(k\)的窗口,输出窗口位于每个位置下的下的最大最小值 嗯,题目很好理解,st表或者线段树过的先别说话,我们来看看另一种方法 我们维护一个长度为k的队列,使得队列的开头为答案,那么我们每次只需要输出开头就好了.这个想法很好

51nod:1689 逛街

原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1689 一开始想枚举逛街的终点,然后开两个大根堆维护b值,分别保证喜爱店不少于k,以及在此前提下逛到的店尽可能多.具体实现是维持第一个堆元素数为k,每加入一个元素,如果c为1,就丢进第一个堆,并把堆顶丢到第二个,c为0直接丢进第二个.如果两个堆的元素b值之和超过T,就从第二个堆删元素. 但是这种写法最后的删元素部分有可能删去对答案有贡献的点,这时再把丢掉的元素

3304 水果姐逛水果街Ⅰ

3304 水果姐逛水果街Ⅰ 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 水果姐今天心情不错,来到了水果街. 水果街有n家水果店,呈直线结构,编号为1~n,每家店能买水果也能卖水果,并且同一家店卖与买的价格一样. 学过oi的水果姐迅速发现了一个赚钱的方法:在某家水果店买一个水果,再到另外一家店卖出去,赚差价. 就在水果姐窃喜的时候,cgh突然出现,他为了为难水果姐,给出m个问题,每个问题要求水果姐从第