Luogu [P1638 exhibition] (ruler method)

Posted by Rhysyngsun on Fri, 08 Nov 2019 20:36:03 +0100

Link

https://www.luogu.org/problemnew/show/P1638

Description

The exhibition hall is displaying pictures drawn by the best M painters in the world. wangjy wants to see the works of these masters in the Expo Hall.

However, there is a very strange rule in the exhibition hall, that is, when buying tickets, two numbers must be stated, a and B, which represent all the pictures between the A and B pictures (including a and b) in the exhibition, and the price of the tickets is one yuan per picture.

  in order to see more famous teachers' paintings, wangjy hopes to see all famous teachers' paintings (at least one each) after entering the venue. But he wanted to save money... As a friend of wangjy, he asked you to write a program to determine the a value and b value when he bought tickets.

  given a sequence containing kkk numbers, the minimum interval containing kkk numbers at the same time can be obtained. If there are several minimum intervals of the same length, the interval with the smallest left endpoint can be output.

Solution

  use two pointers to maintain the interval. Consider maintaining an interval containing kkk numbers. Move the right pointer continuously to the right, and move the left pointer to the right, and ensure the kkk numbers. Update the minimum interval to be searched at the same time.

About

Generally, ruler method is used to solve interval problems with monotonicity, and some problems can also be solved by dichotomy. It is often possible to convert nonmonotonic intervals into monotonic intervals, and then use the rule method.

Code

// luogu-judger-enable-o2
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
//#include<unordered_map>
using namespace std;

#define maxn 1000900
#define inf 0x3f3f3f3f
typedef long long ll;
struct edge{
    int u,v,next,w; 
}e[2];

int head[1],cnt;
void add(int x,int y,int w){
    e[cnt].u=x;
    e[cnt].v=y;
    e[cnt].w=w;
    e[cnt].next=head[x];
    head[x]=cnt++;
    e[cnt].u=y;
    e[cnt].v=x;
    e[cnt].w=w;
    e[cnt].next=head[y];
    head[y]=cnt++;
}

int read(){
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')f=-1;
        c=getchar(); 
    }
    while(c>='0'&&c<='9'){
        x=x*10+c-'0';
        c=getchar();
    }
    return x*f;
}


int n,m,a[maxn],cot[2005];

int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++)
        a[i]=read();
    int L=1,R=1,l=inf,r,num=1,len=n;
    cot[a[L]]++;
    while(R<=n&&L<=R){
        if(cot[a[L]]>1){
            cot[a[L]]--;
            L++;
        }else if(++cot[a[++R]]==1)
                num++;
        if(num==m){
            if(len>R-L+1)
                len=R-L+1,l=L,r=R;
            else if(len==R-L+1&&l>L)
                l=L,r=R;
        }
    }
    cout<<l<<" "<<r<<endl;
}

We insist on one thing not because it will work, but because we firmly believe that it is right to do so.
——Javier