51nod-1686 第K大区间(二分+尺取法)
2016-06-01 22:08
274 查看
题目链接:
第K大区间
基准时间限制:1 秒 空间限制:131072 KB
定义一个区间的值为其众数出现的次数。
现给出n个数,求将所有区间的值排序后,第K大的值为多少。
Input
Output
Input示例
Output示例
第K大区间
基准时间限制:1 秒 空间限制:131072 KB
定义一个区间的值为其众数出现的次数。
现给出n个数,求将所有区间的值排序后,第K大的值为多少。
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 题意: 思路: 先把数组都离散为[1,n]的数,注意相等的; 再二分答案t,check区间众数大于等于t的区间有多少个;(可以设区间众数大于等于t的区间为合法区间) check的时候采用尺取法,按顺序枚举每个区间的左端点i,然后找到区间右端点的最小值;以这个左端点为合法区间的方案数为n-(r-1); 复杂度为O(nlogn) AC代码:
//#include <bits/stdc++.h> #include <vector> #include <iostream> #include <queue> #include <cmath> #include <map> #include <cstring> #include <algorithm> #include <cstdio> using namespace std; #define Riep(n) for(int i=1;i<=n;i++) #define Riop(n) for(int i=0;i<n;i++) #define Rjep(n) for(int j=1;j<=n;j++) #define Rjop(n) for(int j=0;j<n;j++) #define mst(ss,b) memset(ss,b,sizeof(ss)); typedef long long LL; template<class T> void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar()); for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar()); F && (num=-num); } int stk[70], tp; template<class T> inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + '0'); putchar('\n'); } const LL mod=1e9+7; const double PI=acos(-1.0); const LL inf=1e10; const int N=1e5+15; int n,k; int a ,flag ; struct node { int a,id,ans; }po ; int cmp(node x,node y) { if(x.a==y.a)return x.id<y.id; return x.a<y.a; } int cmp1(node x,node y) { return x.id<y.id; } int check(int x) { mst(flag,0); LL ans=0; int num=0; int r=0; Riep(n) { while(1) { int pos=po[r].ans; if(pos!=-1) if(flag[pos]>=x||r>n)break; r++; pos=po[r].ans; flag[pos]++; } ans=ans+n-(r-1); flag[po[i].ans]--; } if(ans>=k)return 1; return 0; } int main() { read(n);read(k); Riep(n)read(po[i].a),po[i].id=i; sort(po+1,po+n+1,cmp); po[0].ans=po[0].a=-1; Riep(n) { if(po[i].a!=po[i-1].a)po[i].ans=i; else po[i].ans=po[i-1].ans; } sort(po+1,po+n+1,cmp1); int l=1,r=n; while(l<=r) { int mid=(l+r)>>1; if(check(mid))l=mid+1; else r=mid-1; } print(l-1); return 0; }
相关文章推荐
- STM32F0xx_TIM输入捕获(计算频率)配置详细过程
- ORACLE数据库事务隔离级别
- c++第6次实验 作业
- Error:(1, 0) Plugin is too old, please update to a more recent version报错
- 机器学习基础知识
- 【一天一道LeetCode】#76. Minimum Window Substring
- numpy基础操作
- MVP模式
- kafka学习一:简介
- Topcoder srm div2 500
- 【一天一道LeetCode】#76. Minimum Window Substring
- Java基础02——Java语言基础(关键字、标识等)
- 第二阶段冲刺第八天
- Learning ReactNative (一) : JavaScript模块基本原理与用法
- 对于JavaScript对象的prototype和__proto__的理解
- 欧几里德与扩展欧几里德算法(转)
- 第三次上机作业
- leetcode Reverse Linked List II
- 栈+哈希表(或者稀疏数组)解决安卓购物车新添加货物置顶的问题
- linux locale和字符集