【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 }