nowcoder911L 最优子区间
2024-09-08 01:43:16
思路
用\(f(i,j)\)表示前i个元素,以i为右端点,j为左端点时的答案。
用个"区间修改,单点查询"的线段树维护出第二维。在从左往右枚举i的过程中。将\([lst_i+1,i]\)的答案+1.将\([lst_{lst_i}+1,lst_i]\)的答案-1。
代码
/*
* @Author: wxyww
* @Date: 2019-06-05 11:13:19
* @Last Modified time: 2019-06-05 11:39:04
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 100000 + 100;
ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int tree[N << 2],lazy[N << 2];
void pushdown(int rt) {
if(lazy[rt]) {
tree[rt << 1] += lazy[rt];
tree[rt << 1 | 1] += lazy[rt];
lazy[rt << 1] += lazy[rt];
lazy[rt << 1 | 1] += lazy[rt];
lazy[rt] = 0;
}
}
void update(int rt,int l,int r,int L,int R,int c) {
if(l >= L && r <= R) {
lazy[rt] += c;
tree[rt] += c;
return;
}
pushdown(rt);
int mid = (l + r) >> 1;
if(L <= mid) update(rt << 1,l,mid,L,R,c);
if(R > mid) update(rt << 1 | 1,mid + 1,r,L,R,c);
tree[rt] = max(tree[rt << 1],tree[rt << 1 | 1]);
}
int pos[N],ans,lst[N];
int main() {
int n = read();
int ans = 0;
for(int i = 1;i <= n;++i) {
int x = read();
if(pos[x]) lst[i] = pos[x];
pos[x] = i;
if(lst[i]) update(1,1,n,lst[lst[i]] + 1,lst[i],-1);
update(1,1,n,lst[i] + 1,i,1);
ans = max(ans,tree[1]);
}
cout<<ans;
return 0;
}
最新文章
- display:inline-block的间隙问题和解决办法
- MultiTouch————多点触控,伸缩图片,变换图片位置
- [知乎] 刚开始学习 iOS 开发有什么书推荐呢?
- c++模板库(简介)
- makefile中的shell语法
- 监控服务器JVM内存运行
- Right Column - 右侧栏目
- Android 获取SDCard中某个目录下图片
- 198,House Robber
- oracle 选择最频繁出现之前,5文章数据
- 使用JAXB解析xml文件(一)
- 创建一个 Spring Boot 项目,你会几种方法?
- dede首页、列表页调用非缩略图
- pygame学习点滴
- 移动端常用UI框架
- JPA、Hibernate、Spring data jpa之间的关系,终于明白了
- 交换路由中期测验20181226(动态路由配置与重分发、NAT转换、ACL访问控制列表)
- python - class类(归一化设计)
- 2012年蓝桥杯省赛A组c++第4题(电视台答题比赛)
- cocos2d-x C++ 判断当前平台宏定义大全