题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6602

题目大意为求最长的区间,满足C种数字在区间内要么不出现,要么出现的次数都不小于K。

大致的分析一下,可以知道对于以R为右端点的区间来说,每种颜色的合法区间在[1~出现k次]和(上一次出现~下一次出现)。PS:[]为闭区间,()为开区间。

所以可以线段树维护一下,枚举区间右端点,然后在线段树上将上一次更新这种颜色的操作撤销(上次是+1,则当前-1),然后再次更新(+1)。

对于每个区间右端点,最大的有效区间为线段树上种类为C的最左边的位置。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#define lson l,mid,i<<1
#define rson mid+1,r,i<<1|1
using namespace std;
typedef long long ll;
const int maxn = 2e5 + ;
const ll mod = ;
int Max[maxn * ], lazy[maxn * ];
vector<int>cnt[maxn];
int num[maxn];
int n, c, k;
void up(int i) {
Max[i] = max(Max[i << ], Max[i << | ]);
}
void down(int i) {
if (lazy[i]) {
lazy[i << ] += lazy[i];
lazy[i << | ] += lazy[i];
Max[i << | ] += lazy[i];
Max[i << ] += lazy[i];
lazy[i] = ;
}
}
void build(int l, int r, int i) {
Max[i] = lazy[i] = ;
if (l == r)
return;
int mid = l + r >> ;
build(lson);
build(rson);
up(i);
}
void update(int L, int R, int k, int l, int r, int i) {
if (L > R)return;
if (L <= l && r <= R) {
Max[i] += k;
lazy[i] += k;
return;
}
down(i);
int mid = l + r >> ;
if (L <= mid)update(L, R, k, lson);
if (R > mid)update(L, R, k, rson);
up(i);
}
int query(int l, int r, int i) {
if (l == r)return l;
int ans = -, mid = l + r >> ;
down(i);
if (Max[i << ] == c)ans = query(lson);
else if (Max[i << | ] == c)ans = query(rson);
return ans;
}
int a[maxn];
int main() {
while (scanf("%d%d%d", &n, &c, &k) != EOF) {
for (int i = ; i <= c; i++)
cnt[i].clear(), cnt[i].push_back(), num[i] = ;
for (int i = ; i <= n; i++) {
scanf("%d", &a[i]);
cnt[a[i]].push_back(i);
}
build(, n, );
for (int i = ; i <= c; i++) {
cnt[i].push_back(n + );
update(cnt[i][] + , cnt[i][] - , , , n, );
}
int ans = ;
for (int i = ; i <= n; i++) {
update(cnt[a[i]][num[a[i]]] + , cnt[a[i]][num[a[i]] + ] - , -, , n, );
if (num[a[i]] >= k)
update(, cnt[a[i]][num[a[i]] - k + ], -, , n, );
num[a[i]]++;
update(cnt[a[i]][num[a[i]]] + , cnt[a[i]][num[a[i]] + ] - , , , n, );
if (num[a[i]] >= k)
update(, cnt[a[i]][num[a[i]] - k + ], , , n, );
int q = query(, n, );
if (q != -)
ans = max(ans, i - q + );
}
printf("%d\n", ans);
}
}

最新文章

  1. Ubuntu15.04安装不完全指南
  2. CentOS 7.1编译安装PHP7
  3. Update Request
  4. socket阻塞与非阻塞,同步与异步
  5. Ahead-of-time compilation(AOT)
  6. TCP和UDP Socket
  7. hdu 1548 A strange lift 宽搜bfs+优先队列
  8. window.showModalDialog的传值和返回值
  9. php web qq第三方登录
  10. SpringMVC(三) —— 参数绑定和数据回显
  11. MyEclipse调整项目的顺序
  12. vueRouter 子路由嵌套
  13. CSS之清除浮动(span/clearfix)
  14. git-代码同步至github
  15. Javascript - Vue - 指令
  16. 16S 基础知识、分析工具和分析流程详解
  17. 最小子串覆盖 &#183; Minimum Window Substring
  18. HDU 3038 How Many Answers Are Wrong(带权并查集,真的很难想到是个并查集!!!)
  19. HDFS RAID实现方案(转)
  20. unity 统一替换shader

热门文章

  1. webpack Entrypoint undefined = index.html
  2. vue请求数据
  3. js倒计时功能中newData().getTime()在iOS下会报错,显示 nan
  4. [UVa1057] Routing
  5. 【leetcode】All Paths From Source to Target
  6. 【leetcode】313. Super Ugly Number
  7. js 获取滚动位置,滚动到指定位置,平滑滚动
  8. Python3 实现FTP功能
  9. python新动态执行 文件头标识 禁止断言
  10. YJJ&#39;s Salesman