HDU 6602 Longest Subarray (线段树)
题意:
1e5的数组,c(1e5)种数字求最长的子串,使得其中每个出现的数字出现的次数为0次或者大于k次
思路:
枚举右端点i,维护当前右端点时,每个左端点的可行元素数量,当且仅当可行元素为c时更新答案
每次用最左边的可行的左端点与当前右端点更新答案
对于每个元素,如果它从i往左第1次出现的元素为pos1,第k次出现的为pos2
那么该元素的可行区域为[1,pos2]与[pos1+1,i]
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1 using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
const int mod = 1e9+;
const int maxn = 2e5+;
const int maxm = 4e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); int n,c,k;
int a[maxn];
vector<int>v[maxn];
int mx[maxn<<];
int addv[maxn<<];
void build(int l, int r, int root){
int mid = (l+r)>>;
if(l==r){mx[root]=c;return;}
build(lson);
build(rson);
mx[root]=max(mx[lc],mx[rc]);
addv[root]=;
return;
}
void pushdown(int l, int r, int root){
if(addv[root]){
addv[lc]+=addv[root];
addv[rc]+=addv[root];
mx[lc]+=addv[root];
mx[rc]+=addv[root];
addv[root]=;
}
return;
}
void update(int x, int y, int val, int l, int r, int root){
int mid = (l+r)>>;
if(x<=l&&r<=y){
addv[root]+=val;
mx[root]+=val;
return;
}
pushdown(l,r,root);
if(x<=mid)update(x,y,val,lson);
if(y>mid)update(x,y,val,rson);
mx[root]=max(mx[rc],mx[lc]);
return;
}
int ask(int l, int r, int root){
int mid = (l+r)>>;
if(l==r){
if(mx[root]==c)return l;
else return inf;
}
pushdown(l,r,root);
if(mx[lc]==c)return ask(lson);
else if(mx[rc]==c)return ask(rson);
return inf;
} int main(){
while(~scanf("%d %d %d", &n, &c, &k)){
for(int i = ; i <= n; i++){v[i].clear();v[i].pb();}
for(int i = ; i <= n; i++){
scanf("%d", &a[i]);
}
build(,n,);
int ans = ;
for(int i = ; i <= n; i++){
if((int)v[a[i]].size()>k){
int l = v[a[i]][v[a[i]].size()-k];
int r = v[a[i]].back();
update(l+,r,,,n,);
v[a[i]].pb(i);
l=v[a[i]][v[a[i]].size()-k];
r=v[a[i]].back();
update(l+,r,-,,n,);
}
else{
update(v[a[i]].back()+,i,-,,n,);
v[a[i]].pb(i);
if((int)v[a[i]].size()>k){
int l = v[a[i]][v[a[i]].size()-k];
update(,l,,,n,);
}
}
int L = ask(,n,);
ans=max(ans,max(,i-L+));
}
printf("%d\n",ans);
}
return ;
}
/*
7 5 2
3 1 5 2 5 2 3 */
HDU 6602 Longest Subarray (线段树)的更多相关文章
- 2019杭电多校第二场hdu6602 Longest Subarray(线段树)
Longest Subarray 题目传送门 解题思路 本题求一个最大的子区间,满足区间内的数字要么出现次数大于等于k次,要么没出现过.给定区间内的数字范围是1~c. 如果r为右边界,对于一种数字x, ...
- [2019杭电多校第二场][hdu6602]Longest Subarray(线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6602 题目大意为求最长的区间,满足C种数字在区间内要么不出现,要么出现的次数都不小于K. 大致的分析一 ...
- 2019杭电多校二 L. Longest Subarray (线段树)
大意: 给定序列$a$, 元素范围$[1,C]$, 求一个最长子序列, 满足每个元素要么不出现, 要么出现次数$\le K$. 枚举右端点, 考虑左端点合法的位置. 显然一定是$C$种颜色合法位置的交 ...
- hdu 5700区间交(线段树)
区间交 Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
- Hdu 3564 Another LIS 线段树+LIS
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...
- HDU 5091---Beam Cannon(线段树+扫描线)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5091 Problem Description Recently, the γ galaxies bro ...
- HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 4031 Attack(线段树/树状数组区间更新单点查询+暴力)
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others) Total Sub ...
随机推荐
- xshell连接kali linux虚拟机
这次测试一波三折 刚开始在百度经验看的先修改ssh参数,蓝色的字是百度的,重点都在图片上 1.修改sshd_config文件,命令为: vi /etc/ssh/sshd_config 将#Passwo ...
- hexo搭建博客系列(三)美化主题
文章目录 其他搭建 1. 添加博客图标 2. 鼠标点击特效(二选一) 2.1 红心特效 2.2 爆炸烟花 3. 设置头像 4. 侧边栏社交小图标设置 5. 文章末尾的标签图标修改 6. 访问量统计 7 ...
- 【转】常见Java面试题 – 第一部分:非可变性(Immutability)和对象引用(Object reference)
ImportNew注: 本文是ImportNew编译整理的Java面试题系列文章之一.请看此系列相关面试题.你可以从这里查看全部的Java面试系列. 一些比较核心的Java问题经常会用来考验面试者的J ...
- python循环语句(while和for)
循环语句分成两种,while循环 和 for循环 作用:可以使指定的代码块重复指定的次数 while循环: # 语法: # while 条件表达式 : # 代码块 # else : # 代码块 # 执 ...
- es5和es6中查找数组中的元素
let array = [1,2,3,4,5] //es5 let find = array.filter(function (item){ return item %2 === 0//返回满足条件的 ...
- idea 2019.3 最新版破解教程
背景 最近,idea又被整治了,所以一大批激活码都失效了.我之前已经有2018版的永久激活了,所以非常淡定~,也没打算升级版本.但是,最近发现周围的人都在讨论这个问题.于是,我也找到了2019.3最新 ...
- Activiti接受任务(receiveTask)
Activiti接受任务(receiveTask) 作者:Jesai 前言: Activiti接受任务(receiveTask)其实和Activiti的手动任务是差不多的,不过手动任务是直接通过,而A ...
- 如何构建可伸缩的Web应用?
为什么要构建可伸缩的Web应用? 想象一下,你的营销活动吸引了很多用户,在某个时候,应用必须同时为成千上万的用户提供服务,这么大的并发量,服务器的负载会很大,如果设计不当,系统将无法处理. 接下来发生 ...
- kafka 中 zookeeper 具体是做什么的?
zookeeper 是 kafka 不可分割的一部分,可见其重要程度,所以我们有必要了解一下 zookeeper 在 kafka 中的具体工作内容. 而且,这也是面试时经常问的. zookeeper ...
- Java单体应用 - Markdown - 01.简介
原文地址:http://www.work100.net/training/monolithic-markdown.html 更多教程:光束云 - 免费课程 简介 序号 文内章节 视频 1 概述 2 特 ...