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 = n, l = 1, r = n;
    while (1){
        while (en < n&&num < m){
            if (vis[a[en++]]++ == 0)num++;
        }
        if (num < m)break;
        if (res>en - st){ res = en - st; l = st + 1; r = en; }
        if (--vis[a[st++]] ==0 )num--;
    }
    cout << l << " " << r << endl;
}

原文地址:https://www.cnblogs.com/ALINGMAOMAO/p/10460754.html

时间: 2024-10-07 17:08:23

P1638 逛画展(直尺法)的相关文章

洛谷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 =

逛画展

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

【Luogu1638】逛画展

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

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(); } whil

单调队列,单调栈相关

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

POJ3061 Subsequence

题目大意:给定长度为n的整列整数a[0],a[1],--a[n-1],以及整数S,求出总和不小于S的连续子序列的长度的最小值. PS:用二分或者直尺法.省赛热身. #include <cstdio> #include <cstdlib> #include <vector> #include <algorithm> #include <cstring> using namespace std; const int INF = 0x3fffff; v

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,就从第二个堆删元素. 但是这种写法最后的删元素部分有可能删去对答案有贡献的点,这时再把丢掉的元素