洛谷P4065 [JXOI2017]颜色(线段树)
题意
Sol
线段树板子题都做不出来,真是越来越菜了。。
根据题目描述,一个合法区间等价于在区间内的颜色没有在区间外出现过。
所以我们可以对于每个右端点,统计最长的左端点在哪里,刚开始以为这个东西有单调性,但事实并不是这样。。
我们统计出对于每个颜色最优的位置\(r_i\)和最左的位置\(l_i\)
那么对于某个左端点\(j\),如果\(r_j > i\),那么\(j\)以及它左侧的点都是不能选的,这里可以用堆+multiset维护。
若\(r_j \leqslant i\),那么\((l_j, r_j]\)都是不能选的。
然后直接线段树区间赋值就好了
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define Fin(x) freopen(#x".in", "r", stdin);
#define Pair pair<int, int>
#define fi first
#define se second
template<typename A, typename B> inline bool chmax(A &x, B y) {return x < y ? x = y, 1 : 0;}
template<typename A, typename B> inline bool chmin(A &x, B y) {return x > y ? x = y, 1 : 0;}
#define LL long long
using namespace std;
const int MAXN = 2e6 + 10, INF = 1e9 + 10;
inline int read() {
char c = getchar(); int x = 0, f = 1;
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 N, a[MAXN], r[MAXN], l[MAXN], tag[MAXN];
multiset<int> s;
priority_queue<Pair, vector<Pair>, greater<Pair> > q;
void Erase(int x) {
auto it = s.find(x);
s.erase(it);
}
#define ls k << 1
#define rs k << 1 | 1
int f[MAXN], sum[MAXN];
void update(int k) {
sum[k] = sum[ls] + sum[rs];
}
void ps(int k) {
sum[k] = 0; f[k] = 1;
}
void pushdown(int k) {
if(!f[k]) return ;
ps(ls); ps(rs);
f[k] = 0;
}
void Build(int k, int l, int r) {
f[k] = 0;
if(l == r) {sum[k] = 1; return ;}
int mid = l + r >> 1;
Build(ls, l, mid); Build(rs, mid + 1, r);
update(k);
}
int Query(int k, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) return sum[k];
pushdown(k);
int mid = l + r >> 1;
if(ql > mid) return Query(rs, mid + 1, r, ql, qr);
else if(qr <= mid) return Query(ls, l, mid, ql, qr);
else return Query(ls, l, mid, ql, qr) + Query(rs, mid + 1, r, ql, qr);
}
void Mem(int k, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) {ps(k); return ;}
pushdown(k);
int mid = l + r >> 1;
if(ql <= mid) Mem(ls, l, mid, ql, qr);
if(qr > mid) Mem(rs, mid + 1, r, ql, qr);
update(k);
}
void solve() {
N = read(); int mx = 0;
for(int i = 1; i <= N; i++) l[i] = INF, r[i] = 0, tag[i] = 0;
for(int i = 1; i <= N; i++) a[i] = read(), chmax(r[a[i]], i), chmin(l[a[i]], i), chmax(mx, a[i]);
Build(1, 1, N);
LL ans = 0;
for(int i = 1; i <= N; i++) {
q.push({r[a[i]], i}); s.insert(i);
if(r[a[i]] == i)
if(l[a[i]] + 1 <= i) Mem(1, 1, N, l[a[i]] + 1, i);
int mx = 0;
while(!q.empty() && q.top().fi <= i)
Erase(q.top().se), q.pop();
if(!s.empty()) {
auto it = s.end(); it--;
mx = (*it);
}
if(mx + 1 <= i) ans += Query(1, 1, N, mx + 1, i);
}
cout << ans << '\n';
}
signed main() {
// Fin(a);
for(int T = read(); T--; solve());
return 0;
}
洛谷P4065 [JXOI2017]颜色(线段树)的更多相关文章
- 【BZOJ】1012: [JSOI2008]最大数maxnumber /【洛谷】1198(线段树)
Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插 ...
- 洛谷题解P4314CPU监控--线段树
题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...
- 洛谷P3372/poj3468(线段树lazy_tag)(询问区间和,支持区间修改)
洛谷P3372 //线段树 询问区间和,支持区间修改 #include <cstdio> using namespace std; struct treetype { int l,r; l ...
- 洛谷P1558 色板游戏 [线段树]
题目传送门 色板游戏 题目背景 阿宝上学了,今天老师拿来了一块很长的涂色板. 题目描述 色板长度为L,L是一个正整数,所以我们可以均匀地将它划分成L块1厘米长的小方格.并从左到右标记为1, 2, .. ...
- [JXOI2017]颜色 线段树扫描线 + 单调栈
---题面--- 题解: 首先题目要求删除一些颜色,换个说法就是要求保留一些颜色,那么观察到,如果我们设ll[i]和rr[i]分别表示颜色i出现的最左边的那个点和最右边的那个点,那么题目就是在要求我们 ...
- 洛谷P3707 [SDOI2017]相关分析(线段树)
题目描述 Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等. Frank不仅喜欢观测,还喜欢分析观测到的数据.他经常分析两个 ...
- 洛谷$P2486\ [SDOI2011]$染色 线段树+树链剖分
正解:线段树+树链剖分 解题报告: 传送门$QwQ$ 其实是道蛮板子的题,,,但因为我写得很呆然后写了贼久之后发现想法有问题要重构,就很难受,就先写个题解算了$kk$ 考虑先跑个树剖,然后按$dfn$ ...
- 洛谷P5111 zhtobu3232的线段树
题意:给定线段树,上面若干个节点坏了,求能表示出多少区间. 区间能被表示出当且仅当拆出来的log个节点都是好的. 解:每个区间在最浅的节点处计算答案. 对于每个节点维护从左边过来能有多少区间,从右边过 ...
- 洛谷P3960 列队 NOIp2017 线段树/树状数组/splay
正解:动态开点线段树 解题报告: 传送门! 因为最近学主席树的时候顺便get到了动态开点线段树?刚好想起来很久很久以前就想做结果一直麻油做的这题,,,所以就做下好了QAQ 然后说下,这题有很多种方法, ...
随机推荐
- mysql连接失败HikariPool错误
1. mysql连接失败HikariPool错误 1.1. 异常 com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Exception during ...
- Core 读取配置文件
新建控制台 static void Main(string[] args) { Console.WriteLine("Hello World!"); //获取应用程序的当前工作目录 ...
- TensorFlow中的变量和常量
1.TensorFlow中的变量和常量介绍 TensorFlow中的变量: import tensorflow as tf state = tf.Variable(0,name='counter') ...
- .NET Core 如何调用 WebService
0.使用背景 因为现在的项目都是基于 .NET Core 的,但是某些需要调用第三方的 WebService 服务,故有了此文章.其基本思路是通过微软提供的 Svcutil 工具生成代理类,然后通过 ...
- C++版 - 剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题,ZOJ 1088:System Overload类似)题解
剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题) 原书题目:0, 1, - , n-1 这n个数字排成一个圈圈,从数字0开始每次从圆圏里删除第m个数字.求出这个圈圈里剩下的最后一个数字 ...
- Execution failed for task ':app:processDebugResources'
经常会遇到突然AndroidStudio编译不了程序,报错误: Execution failed for task ':app:processDebugResources'. > Failed ...
- restTemplate.postForObject上传文件中文乱码(???.xls)
一.问题描述 项目中, 使用restTemplate上传文件时, 文件名中文乱码, 一串问号, 源文件名为: 测试中文乱码哦哦哦.zip, 通过restTemplate.postForObject调用 ...
- excel 中批量生成mysql的脚本
一.假设你的表格有A.B.C三列数据,希望导入到你的数据库中表格table,对应的字段分别是col1.col2.col3 二.在你的表格中增加一列,利用excel的公式自动生成sql语句,具体方法如下 ...
- Canal 源码走读
前言 canal 是什么? 引用一下官方回答: 阿里巴巴mysql数据库binlog的增量订阅&消费组件 canal 能做什么? 基于日志增量订阅&消费支持的业务: 数据库镜像 数据库 ...
- vue开发中vue-resource + canvas 图片压缩、上传、预览
1.使用vue-resource上传,也可以自定义ajax上传: 2.使用<input type="file" @change="submit()" na ...