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 ...
随机推荐
- 最新IDEA永久激活攻略
前言 写这篇文章的原因是我最近想自己写两个项目,却发现自己的IDEA过期了,对,就是那个JAVA编辑器,于是研究了一下IDEA的激活.发现网上的攻略大多数不可用. 当然这里推荐大家去官网购买正版使用. ...
- MySQL快速回顾:高级查询操作
8.1 排序数据 检索出的数据并不是以纯粹的随机顺序显示的.如果不排序,数据一般将以它在底层表中出现的顺序显示.这可以是数据最初添加到表中的顺序.但是,如果数据后来进行过更新或删除,则此顺序将会受到M ...
- python封装简介
1.效果图: 对比一: 对比二: 2.学习来源代码: # 封装是面向对象的三大特性之一 # 封装指的是隐藏对象中一些不希望被外部所访问到的属性或方法 # 如何隐藏一个对象中的属性? # - 将对象的属 ...
- nginx服务无法停止(Windows)
本人一般停止nginx服务都是通过Windows自带的任务管理器来强制结束nginx进程实现的,如图 2.但是 这次我通过同样的方法来结束nginx服务,发现nginx的进程无法结束 3.首先我要 ...
- Akka Java 中文文档
Akka Java 中文文档 Introduction What is Akka? | 什么是Akka? Why Akka? | 为什么选择Akka? Getting Started | Akka入门 ...
- springcloud复习2
Hystrix断路器 Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时.异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导 ...
- Python判断一个字符串是否包含某个指定的字符串
成员操作符 in str = "string test string test" find1 = "str" find2 = "test" ...
- minikube 设置CPU和内存
安装minikube之后,第一次sudo minikube start 时,设置参数--cpus int --memory int . 如果需要更改设置,需要将缓存文件$HOME/.minikube ...
- Nmap使用教程(一)
基本扫描技术 扫描单个网络 nmap 192.168.1.1/www.baidu.com 扫描多个网络/目标 nmap 192.168.1.1 192.168.1.2 #将扫描同个网段内不同的ip地址 ...
- 个人任务Day3
昨日成果: 学习有关java的网络爬虫知识. 今日任务: 向数据库中完善数据,并写出选择查看团队博客的界面.