51Nod——T 1686 第K大区间
https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1686
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
收藏
关注
Input
第一行两个数n和k(1<=n<=100000,k<=n*(n-1)/2) 第二行n个数,0<=每个数<2^31
Output
一个数表示答案。
Input示例
4 2 1 2 3 2
Output示例
2
二分区间的值 x (logn)
枚举一个右端点,记录[l,r]之间每个数的出现个数(离散化,map统计)
如果一个数在[l,r]中的出现个数>=x,则 当 r 属于[r+1,n] 中时,同样满足
满足时,不断缩小l,判断每个区间的情况 (o(n))
nlogn
1 #include <algorithm> 2 #include <cstring> 3 #include <cstdio> 4 5 inline void read(int &x) 6 { 7 x=0; register char ch=getchar(); 8 for(; ch>'9'||ch<'0'; ) ch=getchar(); 9 for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0'; 10 } 11 12 const int N(100005); 13 int n,k,b[N]; 14 15 struct Node { 16 int num,id; 17 bool operator < (const Node&x)const 18 { 19 return num<x.num; 20 } 21 }a[N]; 22 23 int L,R,Mid,ans,cnt[N]; 24 inline bool check(int x) 25 { 26 memset(cnt,0,sizeof(cnt)); 27 int l=1,r=1,ret=0; 28 for(; r<=n; ++r) 29 { 30 cnt[b[r]]++; 31 if(cnt[b[r]]>=x) 32 { 33 ret+=n-r+1; 34 cnt[b[l++]]--; 35 for(; cnt[b[r]]>=x&&l<r; ) 36 { 37 ret+=n-r+1; 38 cnt[b[l++]]--; 39 } 40 } 41 if(ret>=k) return 1; 42 } 43 return 0; 44 } 45 46 int Presist() 47 { 48 read(n),read(k); 49 for(int i=1; i<=n; ++i) read(a[i].num),a[i].id=i; 50 std::sort(a+1,a+n+1); 51 for(int i=1; i<=n; ++i) 52 b[a[i].id]=(a[i].num!=a[i-1].num)?++a[0].id:a[0].id; 53 for(L=0,R=n; L<=R; ) 54 { 55 Mid=L+R>>1; 56 if(check(Mid)) 57 { 58 ans=Mid; 59 L=Mid+1; 60 } 61 else R=Mid-1; 62 } 63 printf("%d",ans); 64 return 0; 65 } 66 67 int Aptal=Presist(); 68 int main(int argc,char**argv){;}
——每当你想要放弃的时候,就想想是为了什么才一路坚持到现在。