题目:

定义一个区间的值为其众数出现的次数。

现给出n个数,求将所有区间的值排序后,第K大的值为多少。

题解:

答案明显单调,我们考虑二分答案.

转化为判定问题后我们需要观察到一个性质:

如果一个区间的价值已经 >= mid了,那么这个无论左右端点向外延伸多少,区间价值一定仍然 >= mid

所以我们可以考虑找出所有的最小满足限制的区间,然后计算出可延伸区间。

所以我们枚举右端点,根据右端点找出对应的左端点,然后统计答案.

我们发现:根据右端点向右移动,左端点一定也向右移动。

所以我们使用双指针法,每一次计算出右端点所代表的值的上mid-1次出现的位置

用这个位置和左端点指针取max,每一次让ans += 所有<=下标左端点的点的个数.

单次判定\(O(n)\),总体\(O(nlogn)\)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline void read(ll &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const int maxn = 120000;
int last[maxn],nxt[maxn];
int b[maxn],n,a[maxn],c[maxn],pos[maxn];
inline void init(){
memset(last,0,sizeof last);
memset(nxt,0,sizeof nxt);
memset(b,0,sizeof b);
}
inline ll check(int val){
ll ret = 0;
init();memset(c,0,sizeof c);
for(int i=1;i<=n;++i){
last[i] = c[a[i]];
c[a[i]] = i;
}memset(c,0,sizeof c);
for(int i=n;i>=1;--i){
nxt[i] = c[a[i]];
c[a[i]] = i;
}
memset(c,0,sizeof c);
memset(pos,0,sizeof pos);
for(int i=1;i<=n;++i){
if(++c[a[i]] == 1) pos[a[i]] = i;
if(c[a[i]] == val) b[i] = pos[a[i]];
else if(c[a[i]] > val){
b[i] = nxt[b[last[i]]];
}
}
if(val == 1) for(int i=1;i<=n;++i) b[i] = i;
for(int L=0,R=1;R <= n;++R){
L = max(L,b[R]);
ret += L;
}
return ret;
}
int main(){
read(n);ll k;read(k);
for(int i=1;i<=n;++i){
read(a[i]);b[i] = a[i];
}
sort(b+1,b+n+1);
for(int i=1;i<=n;++i){
a[i] = lower_bound(b+1,b+n+1,a[i]) - b;
}
int l = 1,r = n,ans = 0;
while(l <= r){
int mid = (l+r) >> 1;
if(check(mid) >= k) ans = mid,l = mid+1;
else r = mid-1;
}
printf("%d\n",ans);
return 0;
}

51nod 1686 第K大区间 二分瞎搞的更多相关文章

  1. 51NOD 1686 第K大区间 二分

    第k大区间   定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. Input   第一行两个数n和k(1<=n<=100000,k<=n* ...

  2. 51nod 1686 第k大区间

    1686 第K大区间 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. ...

  3. 51nod 1686 第K大区间2

    1685 第K大区间2 定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. 众数(统计学/数学名词)_百度百科 Input 第一行两个数n和k(1<=n ...

  4. 51nod 1686 第K大区间【离散化+二分】

    题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1686 题意: 定义一个区间的值为其众数出现的次数. 现给出n ...

  5. 51Nod 1686 第K大区间(离散化+尺取法)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1686 题意: 思路: 第K大值,所以可以考虑二分法,然后用尺取法去扫描, ...

  6. 【题解】51nod 1686第K大区间

    成功的秘诀,在于克服自己看题解的冲动……[笑哭].自己A掉这题还是灰常开心的~ 以及爱死 two - pointer ! two - pointer 大法是真的好哇……这个题目有上一题的经验:求第\( ...

  7. 1686 第K大区间(尺取+二分)

    1686 第K大区间 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. ...

  8. 1686 第K大区间

    1686 第K大区间 时间限制:1 秒 空间限制:131072 KB   定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. 众数(统计学/数学名词)_百度百 ...

  9. 51nod-1686 第K大区间(二分+尺取法)

    题目链接: 第K大区间 基准时间限制:1 秒 空间限制:131072 KB    定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. Input 第一行两个数 ...

随机推荐

  1. 关于function的一种常用用法

    关于function的一种常用用法 void Share::InitAcrossManager() { GsMgrEvent gsMgrEvents;//保存function的结构体 gsMgrEve ...

  2. Java Enum 比较用 == 还是 eques

    我是把枚举当作常量来使用的,枚举中还有两个自己的属性,关注到这个地方的朋友对枚举已经有了认识,这里就不再编写枚举的demo了,这里我直接说结果吧,在枚举中使用==和equals比较效果是一样的,查看源 ...

  3. 【BZOJ4028】[HEOI2015]公约数数列 分块

    [BZOJ4028][HEOI2015]公约数数列 Description 设计一个数据结构. 给定一个正整数数列 a_0, a_1, ..., a_{n - 1},你需要支持以下两种操作: 1. M ...

  4. debian安装oracle jdk

    1 去官网下载linux jdk https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.htm ...

  5. 【译】Java语言速览:StackOverflow

    Java (请不要与 JavaScript 搞混) 是一种设计为与 Java 虚拟机 (JVM) 一起使用的多用途编程语言.一般称呼安装了相关工具使其可以开发并运行 Java 程序的电脑系统为 &qu ...

  6. 几则js表达式

    过滤大段文本里的标签.标签格式 <...>,如下匹配标签然后替换成空 校验邮箱是否符合: 去掉行首行尾空格: 检测字符串是否包含中文:(utf8编码)

  7. linux c编程:进程控制(四)进程调度

    当系统中有多个进程到时候,哪个进程先执行,哪个进程后执行是由进程的优先级决定的.进程的优先级是由nice值决定的.nice值越小,优先级越高.可以看做越友好那么调度优先级越低.进程可以通过nice函数 ...

  8. CentOS7.x 报错 There are no enabled repos.

    地址 :http://mirrors.163.com/centos/7/os/x86_64/Packages/   wget http://mirrors.163.com/centos/7/os/x8 ...

  9. centos 安装 jdk PostgreSQL

    1.下载: anzhuang  jDK http://blog.csdn.net/youzhouliu/article/details/51183115 ----------------------- ...

  10. C#聚合运算方法

    Aggregate 对集合值执行自定义聚合运算 Average 计算集合平均值 Count 对集合的元素惊醒计数,还可以仅对满足某一谓词函数的元素进行计数 LongCount 对大型集合中的元素进行计 ...