51nod 1686 第K大区间(二分 尺取)
来源:互联网 发布:网店的营销策略数据 编辑:程序博客网 时间:2024/05/21 22:48
题意:定义一个区间的值为其众数出现的次数。现给出n个数,求将所有区间的值排序后,第K大的值为多少。
思路:答案具有单调性,所以可以二分,关键是check的时候怎么统计有多少区间满足>=mid, 我们可以知道假如区间[L, R]满足,那么左右扩大这个区间都是满足的,所以可以尺取,枚举右端点,找到最大的符合条件的l即可,对答案贡献为l,而且l也只会向右动。右端点向右移动一步,有两种情况,一种情况是l不变,另一种是a[r]能与l右边的一个点满足区间出现mid次a[r],这样l就可以跳到这个点。 所以预处理出b[i],表示每个点往前出现第mid个a[i]的位置。
代码:
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 1e5+5;int a[maxn], Hash[maxn];int num[maxn], pos[maxn], pre[maxn], nxt[maxn], b[maxn];ll n, k;ll judge(int x){ if(x == 1) return k; ll cnt = 0; memset(pos, 0, sizeof(pos)); for(int i = 1; i <= n; i++) { pre[i] = pos[a[i]]; pos[a[i]] = i; } memset(pos, 0, sizeof(pos)); for(int i = n; i >= 1; i--) { nxt[i] = pos[a[i]]; pos[a[i]] = i; } memset(pos, 0, sizeof(pos)); memset(num, 0, sizeof(num)); memset(b, 0, sizeof(b)); for(int i = 1; i <= n; i++) { num[a[i]]++; if(num[a[i]] == 1) pos[a[i]] = i; if(num[a[i]] == x) b[i] = pos[a[i]]; if(num[a[i]] > x) b[i] = nxt[b[pre[i]]]; } for(int l = 0, r = 1; r <= n; r++) l = max(l, b[r]), cnt += l; return cnt;}int main(void){ while(cin >> n >> k) { a[0] = -1; for(int i = 1; i <= n; i++) scanf("%d", &a[i]), Hash[i] = a[i]; sort(Hash+1, Hash+1+n); int d = unique(Hash+1, Hash+1+n)-Hash-1; for(int i = 1; i <= n; i++) a[i] = lower_bound(Hash+1, Hash+1+d, a[i])-Hash; int ans, l = 1, r = n; while(l <= r) { int mid = (l+r)/2; if(judge(mid) >= k) ans = mid, l = mid+1; else r = mid-1; } printf("%d\n", ans); } return 0;}
阅读全文
1 0
- 51nod 1686 第K大区间(二分 尺取)
- 51Nod【1686】——1686 第K大区间(尺取+二分)
- 解题报告:51nod 1686 第K大区间 二分+尺取
- 51nod 1686-第K大区间(离散化+二分+尺取)
- 51nod 1686 第K大区间【离散化+二分】
- 51nod 1686 第K大区间 二分好题
- 【二分+Two Pointers】51Nod 1686 第K大区间
- 51nod 1686 第k大区间
- 51nod-1686 第K大区间
- 51Nod-1686-第K大区间
- 51nod 1686 第K大区间
- 51Nod 1686(第K大区间)
- 51nod 1686 第K大区间
- 51nod 1686 第K大区间
- 51nod 1686 第K大区间 (二分+滑动窗口+离散化)
- 51nod 第K大区间
- 【51nod】 第K大区间2(二分+树状数组)
- [二分+树状数组]51 Nod 1685——第K大区间2
- Log4j使用(一):每天生成一个日志文件DailyRollingFileAppender的使用
- 当鼠标拖曳事件碰到iframe(卡死了)
- Javaweb多次调用Rengine re=new Rengine(args, false, new TextConsole()); 报错
- 用TP5 写了一个 字段追加内容的代码
- 置换和轮换(新姿势,摘自黑书)
- 51nod 1686 第K大区间(二分 尺取)
- Java8 Stream 流中的匹配查找方法
- std::ios::sync_with_stdio(false); cin.tie(0);
- 95
- 皮尔逊相关度
- 小程序相对于传统推广的优势所在
- LinkedList、ArrayList、 Vector的区别和详解
- LeetCode70.Climbing Stairs
- Redis 探究底层存储结构