HDU6602 Longest Subarray hdu多校第二场 线段树
HDU6602 Longest Subarray 线段树
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6602
题意:
给你一段区间,让你求最长的区间使得区间出现的数字的个数大于k
题解:
比较巧妙的的线段树更新的做法
我们选择的区间吗,该区间内出现的数字的个数必须要满足条件
我们转换一下,我们以当前点为右端点,往左找一个满足条件的左端点,即可更新答案
我们将每个点给予一个权值C-1,更新这个点的数字上次出现的位置之前到现在这个位置-1的一段减1
如果满足这个点的值出现的次数大于k次的话,我们将上一次满足出现k次出现的一段位置给加上1
最后得到当前位置之前满足条件的左端点更新答案
这里巧妙的使用了条件作为线段树查询的条件,所以线段树查询出来的左端点就是满足条件的最远的左端点
代码:
#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double Pi = acos(-1);
/*
如果右端点固定,对于每种元素,可行的左端点下标是两段连续的区间。
对于每种元素,将它的可行左端点区间在线段树中加1。
当右端点右移的时候,维护C 种元素的可行左端点。
查询时只要询问线段树中札小的、值为C 的下标即可。*/
LL quick_pow(LL x, LL y) {
LL ans = 1;
while(y) {
if(y & 1) {
ans = ans * x % mod;
} x = x * x % mod;
y >>= 1;
} return ans;
}
int n, C, k;
int Max[maxn << 2];
int lazy[maxn << 2];
int pos[maxn << 2];
void push_up(int rt) {
Max[rt] = max(Max[ls], Max[rs]);
pos[rt] = (Max[rt] == Max[ls] ? pos[ls] : pos[rs]);
}
void build(int l, int r, int rt) {
Max[rt] = lazy[rt] = 0;
pos[rt] = l;
if(l == r) return;
int mid = (l + r) >> 1;
build(lson);
build(rson);
}
void push_down(int rt) {
if(lazy[rt]) {
lazy[ls] += lazy[rt];
lazy[rs] += lazy[rt];
Max[ls] += lazy[rt];
Max[rs] += lazy[rt];
lazy[rt] = 0;
}
}
void update(int L, int R, int val, int l, int r, int rt) {
if(L > R) return;
if(L <= l && r <= R) {
Max[rt] += val;
lazy[rt] += val;
return;
}
push_down(rt);
int mid = (l + r) >> 1;
if(L <= mid) update(L, R, val, lson);
if(R > mid) update(L, R, val, rson);
push_up(rt);
}
int query(int L, int R, int l, int r, int rt) {
if(Max[rt] != C) return 0;
if(L <= l && r <= R) {
return pos[rt];
}
int mid = (l + r) >> 1;
push_down(rt);
if(L <= mid) {
int t = query(L, R, lson);
if(t) return t;
}
if(R > mid) return query(L, R, rson);
return 0;
}
vector<int> vec[maxn];
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
while(scanf("%d%d%d", &n, &C, &k) != EOF) {
for(int i = 1; i <= C; i++) {
vec[i].clear();
vec[i].push_back(0);
}
build(1, n, 1);
int ans = 0;
for(int i = 1; i <= n; i++) {
int c;
scanf("%d", &c);
update(i, i, C - 1, 1, n, 1);
update(vec[c].back() + 1, i - 1, -1, 1, n, 1);
vec[c].push_back(i);
int p = vec[c].size() - k - 1;
if(p >= 0) {
update(vec[c][p] + 1, vec[c][p + 1], 1, 1, n, 1);
}
int j = query(1, i, 1, n, 1);
if(!j) continue;
ans = max(ans, i - j + 1);
}
printf("%d\n", ans);
}
return 0;
}
HDU6602 Longest Subarray hdu多校第二场 线段树的更多相关文章
- HDU 4614 Vases and Flowers (2013多校第二场线段树)
题意摘自:http://blog.csdn.net/kdqzzxxcc/article/details/9474169 ORZZ 题意:给你N个花瓶,编号是0 到 N - 1 ,初始状态花瓶是空的,每 ...
- hdu多校第二场1008(hdu6598) Harmonious Army 最小割
题意: 一个军队有n人,你可以给他们每个人安排战士或者法师的职业,有m对人有组合技,组合技的信息是a,b,c,代表如果这两个人是两个战士,则组合技威力为a,一个战士一个法师,威力为b,其中b=a/4+ ...
- hdu多校第二场 1005 (hdu6595) Everything Is Generated In Equal Probability
题意: 给定一个N,随机从[1,N]里产生一个n,然后随机产生一个n个数的全排列,求出n的逆序数对的数量,加到cnt里,然后随机地取出这个全排列中的一个非连续子序列(注意这个子序列可以是原序列),再求 ...
- hdu多校第二场1009 (hdu6599) I Love Palindrome String 回文自动机/字符串hash
题意: 找出这样的回文子串的个数:它本身是一个回文串,它的前一半也是一个回文串 输出格式要求输出l个数字,分别代表长度为1~l的这样的回文串的个数 题解: (回文自动机和回文树是一个东西) 首先用回文 ...
- hdu多校第二场1011 (hdu6601) Keen On Everything But Triangle 主席树
题意: 给定一个数列,每次询问一个区间,问这个区间中的值可组成的周长最大的三角形的周长. 题解: 定理1:给定一些值,这些值中组成边长最大的三角形的三条边的大小排名一定是连续的. 证明:假如第k大,第 ...
- hdu多校第二场 1010 (hdu6600)Just Skip This Problem
题意: 给你一个数x,允许你多次询问yi,然后回答你x xor yi 是否等于yi,询问尽量少的次数以保证能求出xi是几,求出这样询问次数最少的询问方案数. 结果mod1e6+3 题解: 队友赛时很快 ...
- 2019牛客多校第二场 A Eddy Walker(概率推公式)
2019牛客多校第二场 A Eddy Walker(概率推公式) 传送门:https://ac.nowcoder.com/acm/contest/882/A 题意: 给你一个长度为n的环,标号从0~n ...
- hdu 5861 Road 两棵线段树
传送门:hdu 5861 Road 题意: 水平线上n个村子间有 n-1 条路. 每条路开放一天的价格为 Wi 有 m 天的操作,每天需要用到村子 Ai~Bi 间的道路 每条路只能开放或关闭一次. ( ...
- HDU 3016 Man Down (线段树+dp)
HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
随机推荐
- PLAY2.6-SCALA(四) 请求体解析器
一个http请求是一个请求头后面跟着一个请求体,头部信息比较短,可以安全的缓存在内存中,在Play中头部信息使用RequestHeader类进行建模.请求体的内容可能较大,使用流stream的形式进行 ...
- Linux配置redis开机启动(CentOS 7)
https://blog.csdn.net/qq_31803503/article/details/79246205 本次配置linux版本是CentOS 7 首先将 redis-3.2.3/uti ...
- MaxCompute 费用暴涨之存储压缩率降低导致SQL输入量变大
现象:同样的SQL,每天处理的数据行数差不多,但是费用突然暴涨甚至会翻数倍. 分析: 我们先明确MaxCompute SQL后付费的计费公式:一条SQL执行的费用=扫描输入量 ️ SQL复杂度 ️ 0 ...
- 从零学React Native之11 TextInput
TextInput 组件是用来通过键盘输入文字,可以使用View组件和Text组件样式,没有自己特定的样式. 与Text组件类似,TextInput组件内部的元素不再使用FlexBox布局,而采用文本 ...
- FZU 2234 牧场物语【多线程dp】
Problem 2234 牧场物语 Problem Description 小茗同学正在玩牧场物语.该游戏的地图可看成一个边长为n的正方形. 小茗同学突然心血来潮要去砍树,然而,斧头在小茗的右下方 ...
- P4930「FJ2014集训」采药人的路径
题目:P4930「FJ2014集训」采药人的路径 思路: 这篇不算题解,是让自己复习的,什么都没说清楚. 很久没有写点分治了,以前为了赶课件学的太急,板子都没打对就照着题解写题,导致学得很不扎实. 这 ...
- Java练习 SDUT-2240_织女的红线
织女的红线 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 好久不见牛郎哥哥了,织女非常想他,但是她想考验一下牛郎在她不 ...
- 学习C#泛型
C#泛型详解 C#菜鸟教程 C#中泛型的使用
- oracle不明确的索引等级
当ORACLE无法判断索引的等级高低差别,优化器将只使用一个索引,它就是在WHERE子句中被列在最前面的. 举例: DEPTNO上有一个非唯一性索引,EMP_CAT也有一个非唯一性索引. SELECT ...
- 推荐几个web前端比较实用的网站
第一次写博客,说实在的有点紧张和兴奋,哈哈哈哈,本人工作了有两年的时间,平时也有做笔记的习惯,但是都做得乱七八糟的,所以就想通过写博客来记录.好了,废话不多说了,先来几个觉得在工作中使用到的,还不错的 ...