2019年杭电多校第二场 1012题Longest Subarray(HDU6602+线段树)
题目链接
题意
要你找一个最长的区间使得区间内每一个数出现次数都大于等于\(K\)。
思路
我们通过固定右端点考虑每个左端点的情况。
首先对于每个位置,我们用线段树来维护它作为\(C\)种元素的左端点的可行性。
对于每个元素我们用\(vector\)存下它出现的所有下标。
枚举右端点\(i\),对于\([i,i]\)这区间除去\(a_i\)这个数外其他元素都没有出现过,那么它作为左端点的可行性为\(C-1\);对于\(a_i\)上一次出现的位置\(pos\),则\([pos+1,i-1]\)这一段区间做左端点,由于\(a_i\)在\(i\)出现过了,那么\([pos+1,i-1]\)在线段树内的结点均存了\(a_i\)没有出现的情况,因此需要减去。假设从\(y\)是\(a_i\)从\(i\)往左数恰好出现\(K\)次的位置,\(x\)是恰好出现\(K+1\)次的位置,那么\([x+1,y]\)在线段树内的结点没有存\(a_i\)出现\(K\)次的情况,因此需要加上。
查询:对于\(i\),我们考虑最左边作为左端点可行性为\(C\)的位置加一的\(x\)(因为\(x\)在线段树的信息表示的是以\(i\)为右端点,\(x\)为左端点有多少个数满足题目给定的要求,因此找到最小的可行性为\(C\)的下标),那么此时可以选择的区间长度为\(i-x+1\),然后对于所有情况取\(max\)即可。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("/home/dillonh/CLionProjects/Dillonh/in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1000000007;
const int maxn = 100000 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int N, C, K, x;
vector<int> vec[maxn];
struct node {
int l, r, mx, lazy, ans;
}segtree[maxn<<2];
void push_up(int rt) {
segtree[rt].mx = max(segtree[lson].mx, segtree[rson].mx);
//预存从i为右端点,可行性为C下表最小的左端点
if(segtree[rt].mx == segtree[lson].mx) segtree[rt].ans = segtree[lson].ans;
else segtree[rt].ans = segtree[rson].ans;
}
void push_down(int rt) {
int x = segtree[rt].lazy;
segtree[rt].lazy = 0;
segtree[lson].lazy += x;
segtree[rson].lazy += x;
segtree[lson].mx += x;
segtree[rson].mx += x;
}
void build(int rt, int l, int r) {
segtree[rt].l = segtree[rt].ans = l, segtree[rt].r = r;
segtree[rt].mx = segtree[rt].lazy = 0;
if(l == r) return;
int mid = (l + r) >> 1;
build(lson, l, mid);
build(rson, mid + 1, r);
}
void update(int rt, int l, int r, int val) {
if(segtree[rt].l == l && segtree[rt].r == r) {
segtree[rt].mx += val;
segtree[rt].lazy += val;
return;
}
push_down(rt);
int mid = (segtree[rt].l + segtree[rt].r) >> 1;
if(r <= mid) update(lson, l, r, val);
else if(l > mid) update(rson, l, r, val);
else {
update(lson, l, mid, val);
update(rson, mid + 1, r, val);
}
push_up(rt);
}
int query(int rt, int l, int r) {
if(segtree[rt].mx != C) return -1;
if(segtree[rt].l >= l && segtree[rt].r <= r) return segtree[rt].ans;
push_down(rt);
int mid = (segtree[rt].l + segtree[rt].r) >> 1;
if(r <= mid) return query(lson, l, r);
else if(l > mid) return query(rson, l, r);
else {
int tmp = query(lson, l, mid);
if(tmp != -1) return tmp;
return query(rson, mid + 1, r);
}
}
int main() {
while(~scanf("%d%d%d", &N, &C, &K)) {
for(int i = 1; i <= C; ++i) vec[i].clear(),vec[i].push_back(0);
build(1, 1, N);
int ans = 0;
for(int i = 1; i <= N; ++i) {
scanf("%d", &x);
update(1, i, i, C - 1); //单独只考虑[i,i]这个区间,此时其他i-1个元素均没有出现,因此i的作为左端点可行性为C-1
if(vec[x].back() < i - 1) update(1, vec[x].back() + 1, i - 1, -1); //将前面考虑过ai没有出现的情况减去
vec[x].push_back(i);
if(vec[x].size() >= K + 1) {
int pos = vec[x].size() - K - 1;
update(1, vec[x][pos] + 1, vec[x][pos+1], 1); //把前面没有考虑ai出现k次的情况加上
}
int tmp = query(1, 1, i);
if(tmp == -1) continue;
ans = max(ans, i - tmp + 1);
}
printf("%d\n", ans);
}
return 0;
}
2019年杭电多校第二场 1012题Longest Subarray(HDU6602+线段树)的更多相关文章
- 杭电多校第二场1012 L - Longest Subarray ce 线段树
这题是真的秀...我服了...线段树用好了,感觉什么都可以写... 题目大意:给你一个串,问满足以下条件的子串中最长的是多长:对于每个数字,要么在这个子串没出现过,要么出现次数超过k次. 我们对于每一 ...
- 2019年杭电多校第二场 1008题Harmonious Army(HDU6598+最小割+建图)
题目链接 传送门 题意 有\(n\)个士兵,要你给他们分配职业.有\(m\)对关系,对于某一对关系\(u,v\),如果同为勇士则总能力增加\(a\),同法师则增加\(c\),一个勇士一个法师增加\(\ ...
- 2019年杭电多校第二场 1002题Beauty Of Unimodal Sequence(LIS+单调栈)
题目链接 传送门 思路 首先我们对\(a\)正反各跑一边\(LIS\),记录每个位置在前一半的\(LIS\)中应该放的位置\(ans1[i]\),后一半的位置\(ans2[i]\). 对于字典序最小的 ...
- Rikka with Travels(2019年杭电多校第九场07题+HDU6686+树形dp)
目录 题目链接 题意 思路 代码 题目链接 传送门 题意 定义\(L(a,b)\)为结点\(a\)到结点\(b\)的路径上的结点数,问有种\(pair(L(a,b),L(c,d))\)取值,其中结点\ ...
- 2019年杭电多校第一场 1009题String(HDU6586+模拟+单调栈)
题目链接 传送门 题意 给你一个字符串,要你构造一个长为\(k\)的子串使得每个字母出现的次数在\([L_i,R_i](0\leq i\leq26)\)间且字典序最小. 思路 做这种题目就是要保持思路 ...
- 2019年杭电多校第一场 1004题Vacation(HDU6581+数学)
题目链接 传送门 题意 有\(n+1\)辆车要过红绿灯,告诉你车的长度.与红绿灯的起点(题目假设红绿灯始终为绿).车的最大速度,问你第\(0\)辆车(距离最远)车头到达红绿灯起点的时间是多少(每辆车最 ...
- 2019年杭电多校第一场 1002题Operation(HDU6579+线性基)
题目链接 传送门 题意 初始时有\(n\)个数,现在有\(q\)次操作: 查询\([l,r]\)内选择一些数使得异或和最大: 在末尾加入一个数. 题目强制在线. 思路 对于\(i\)我们记录\([1, ...
- 2018 Multi-University Training Contest 2 杭电多校第二场
开始逐渐习惯被多校虐orz 菜是原罪 1004 Game (hdoj 6312) 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6312 虽然披着 ...
- 2019杭电多校第二场hdu6601 Keen On Everything But Triangle
Keen On Everything But Triangle 题目传送门 解题思路 利用主席树求区间第k小,先求区间内最大的值,再求第二大,第三大--直到找到连续的三个数可以构成一个三角形.因为对于 ...
随机推荐
- laravel代码规范强制检查
目录 介绍 代码规范检查与修复 在git commit时自动检查代码规范 后记 介绍 在团队协作开发中,代码规范是必要的.以前的规范都是自己定,然后手动检查,很难做到有效的约束. 现代的PHP,则有得 ...
- Java并发之多线程下竞态条件概念的理解
一.简述 竞态条件(Race Condition):计算的正确性取决于多个线程的交替执行时序时,就会发生竞态条件. 二.常见竞态条件分析 最常见的竞态条件为 1.先检测后执行 执行依赖于检测的结果,而 ...
- Python【每日一问】26
问: [基础题]:输入一行字符,分别统计出其中英文字母.空格.数字和其它字符的个数 [提高题]:一球从 100 米高度自由落下,每次落地后反跳回原高度的一半:再落下,求它在第 10 次落地时,共经过多 ...
- BitSet源码
public class BitSet1 implements Cloneable, java.io.Serializable { // >>>左边补0, << 右边补0 ...
- Docker从入门到实践(3)
三.安装 Docker Docker 分为 CE 和 EE 两大版本.CE 即社区版(免费,支持周期 7 个月),EE 即企业版,强调安全,付费使用,支持周期 24 个月. Docker CE 分为 ...
- Python3 CGI编程实现教程
一.背景说明 虽然很久以前就听说“早期的网站很多通过cgi形式实现”.“C++可通过CGI形式编写网页”,日积月累对CGI也有了一些概念,但一直没真正见过一个实际运行的CGI网站,总归还是有些底气不足 ...
- php中命名空间namespace和use
对于面向对象编程而言,命名空间namespace和use的概念非常重要. 1.根命名空间是反斜线 \ ,有点类似linux中的根目录 / 的那种感觉,但使用var_dump()函数打印时其实是空字符串 ...
- 【转】AXI_Lite 总线详解
目录: · 1.前言 · 2.AXI总线与ZYNQ的关系 · 3 AXI 总线和 AXI 接口以及 AXI 协议 · 3.1 AXI 总线概述 · 3.2 AXI 接口介绍 ·3.3 AXI 协议概述 ...
- AGC038
Contest Page 开题开错翻车场.jpg A sol $A > \frac{W}{2}$或者$B > \frac{H}{2}$的时候无解,否则构造方法长下面这样 #include& ...
- UDP比TCP好用的优势
网络带宽环境变好 在2007年至2015年间,网络的带宽飞速发展,从1.5Mbps的带宽增加到5.1Mbps的带宽,足足增加了4倍,网络环境快速.稳定,所以UDP的丢包率 下降至5%以下,越来越好的网 ...