【USACO11NOV】牛的阵容Cow Lineup 尺取法+哈希

题目描述

Farmer John has hired a professional photographer to take a picture of some of his cows. Since FJ's cows represent a variety of different breeds, he would like the photo to contain at least one cow from each distinct breed present in his herd.
FJ's N cows are all standing at various positions along a line, each described by an integer position (i.e., its x coordinate) as well as an integer breed ID. FJ plans to take a photograph of a contiguous range of cows along the line. The cost of this photograph is equal its size -- that is, the difference between the maximum and minimum x coordinates of the cows in the range of the photograph.
Please help FJ by computing the minimum cost of a photograph in which there is at least one cow of each distinct breed appearing in FJ's herd.
依次给出N头牛的位置及种类,要求找出连续一段,使其中包含所有种类的牛,问:这连续的一段最小长度是多少?

输入

* Line 1: The number of cows, N (1 <= N <= 50,000).

* Lines 2..1+N: Each line contains two space-separated positive  integers specifying the x coordinate and breed ID of a single  cow.  Both numbers are at most 1 billion.

输出

* Line 1: The smallest cost of a photograph containing each distinct  breed ID.

样例输入

6 25 7 26 1 15 1 22 3 20 1 30 1

样例输出

4

提示

There are 6 cows, at positions 25,26,15,22,20,30, with respective breed IDs 7,1,1,3,1,1.

The range from x=22 up through x=26 (of total size 4) contains each of the distinct breed IDs 1, 3, and 7 represented in FJ's herd.

题解:

迟取法:

设k为总牛数

1.L-R之间牛的等于k,L++.

2.小于k,R++.

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int N=50005,MAXN=1000000001,M=500005;
 7 int gi(){
 8     int str=0;char ch=getchar();
 9     while(ch>'9' || ch<'0')ch=getchar();
10     while(ch>='0' && ch<='9')str=str*10+ch-'0',ch=getchar();
11     return str;
12 }
13 struct Ques{
14     int x,id;
15 }a[N];
16 bool comp(const Ques &p,const Ques &q){
17     return p.x<q.x;
18 }
19 int head[M],num=0,ans=MAXN,sum=1;
20 struct Lin{
21     int next,x,cnt;
22 }b[N];
23 void mark(int x,int t)
24 {
25     int p=x%M;
26     for(int i=head[p];i;i=b[i].next)if(x==b[i].x){
27         if(t==1)
28         {
29             if(b[i].cnt==0)sum++;
30             b[i].cnt++;
31         }
32         else
33         {
34             if(b[i].cnt==1)sum--;
35             b[i].cnt--;
36         }
37     }
38 }
39 int Ask(int x)
40 {
41     int p=x%M;
42     for(int i=head[p];i;i=b[i].next)if(x==b[i].x)return b[i].cnt;
43     return 0;
44 }
45 void Clear()
46 {
47     for(int i=1;i<=num;i++)b[i].cnt=0;
48     sum=0;
49 }
50 void init(int x)
51 {
52     int y=x%M;
53     b[++num].next=head[y];
54     b[num].x=x;
55     b[num].cnt=1;
56     head[y]=num;
57 }
58 int main()
59 {
60     int n=gi(),k=0;
61     for(int i=1;i<=n;i++){
62         a[i].x=gi(),a[i].id=gi();
63         if(!Ask(a[i].id))k++,init(a[i].id); 
64     }
65     Clear();
66     sort(a+1,a+n+1,comp);
67     int l=1,r=1;
68     mark(a[1].id,1);
69     while(l<=r && r<=n)
70     {
71         if(sum==k){
72             ans=min(a[r].x-a[l].x,ans);
73             mark(a[l].id,-1);
74             l++;
75         }
76         else
77         {
78             r++;
79             mark(a[r].id,1);
80         }
81     }
82     printf("%d",ans);
83     return 0;
84 } 
原文地址:https://www.cnblogs.com/Yuzao/p/6893872.html