loj2275 「JXOI2017」颜色
枚举右端点,然后看左端点合法情况。
先预处理每个颜色 \(i\) 的最大出现位置 \(max_i\) 和最小出现位置 \(min_i\)。对于枚举右端点在一个位置 \(i\),凡是 \(max_k > i\) 的颜色 \(k\) 都是不能要的。那么要满足右端点往右都合法,就要找出一个 \(j < i\) 且 \(max_{col_j} > i\) 这样的最大的 \(j\)。那么左端点就可以在 \((j,i]\) 之间了。
再来满足左端点往左都合法。对于一个颜色 \(k\),当 \(max_k \leq i\) 时,左端点显然不能在 \((min_k,max_k]\) 之间。线段树+栈解决问题。
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int T, n, col[300005], minn[300005], maxn[300005], sta[300005], din;
const int oo=0x3f3f3f3f;
ll ans;
struct SGT{
int sum[1200005];
bool tag[1200005];
void build(int o, int l, int r){
sum[o] = tag[o] = 0;
if(l==r) ;
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
if(l<=mid) build(lson, l, mid);
if(mid<r) build(rson, mid+1, r);
}
}
void pushDown(int o, int l, int r, int lson, int rson, int mid){
sum[lson] = mid - l + 1;
sum[rson] = r - mid;
tag[lson] = true;
tag[rson] = true;
tag[o] = false;
}
void update(int o, int l, int r, int x, int y){
if(l>r) return ;
if(l>=x && r<=y){
sum[o] = (r - l + 1);
tag[o] = true;
}
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
if(tag[o]) pushDown(o, l, r, lson, rson, mid);
if(x<=mid) update(lson, l, mid, x, y);
if(mid<y) update(rson, mid+1, r, x, y);
sum[o] = sum[lson] + sum[rson];
}
}
int query(int o, int l, int r, int x, int y){
if(l>r) return 0;
if(l>=x && r<=y) return sum[o];
else{
int mid=(l+r)>>1;
int lson=o<<1;
int rson=lson|1;
int re=0;
if(tag[o]) pushDown(o, l, r, lson, rson, mid);
if(x<=mid) re += query(lson, l, mid, x, y);
if(mid<y) re += query(rson, mid+1, r, x, y);
return re;
}
}
}sgt;
int main(){
cin>>T;
while(T--){
scanf("%d", &n);
ans = din = 0;
for(int i=1; i<=n; i++){
scanf("%d", &col[i]);
minn[col[i]] = oo;
maxn[col[i]] = 0;
}
for(int i=1; i<=n; i++){
minn[col[i]] = min(minn[col[i]], i);
maxn[col[i]] = max(maxn[col[i]], i);
}
sgt.build(1, 1, n);
for(int i=1; i<=n; i++){
if(i==maxn[col[i]])
sgt.update(1, 1, n, minn[col[i]]+1, i);
sta[++din] = i;
while(din && maxn[col[sta[din]]]<=i) din--;
int pos=!din?1:sta[din]+1;
ans += (i - pos + 1) - sgt.query(1, 1, n, pos, i);
}
printf("%lld\n", ans);
}
return 0;
}
loj2275 「JXOI2017」颜色的更多相关文章
- 【LOJ】#2275. 「JXOI2017」颜色
题解 我们枚举右端点判断合法的左端点有哪些 首先,记录一下右端点右边的点的pre,也就是这个数字前一个出现的位置,取所有小于枚举右端点r的值中最大的一个做为l,用优先队列维护即可,[l + 1,r]就 ...
- loj2274 「JXOI2017」加法
二分一下,然后从左到右扫描,扫到左端点就把区间 push 到堆里. 每次有点不符合二分的值时,就贪心地选择右端点最远的 add. #include <algorithm> #include ...
- 「SDOI2017」树点涂色 解题报告
「SDOI2017」树点涂色 我sb的不行了 其实一开始有一个类似动态dp的想法 每个点维护到lct树上到最浅点的颜色段数,然后维护一个\(mx_{0,1}\)也就是是否用虚儿子的最大颜色 用个set ...
- LOJ #2116 Luogu P3241「HNOI2015」开店
好久没写数据结构了 来补一发 果然写的时候思路极其混乱.... LOJ #2116 Luogu P3241 题意 $ Q$次询问,求树上点的颜色在$ [L,R]$中的所有点到询问点的距离 强制在线 询 ...
- 「ZJOI2018」历史(LCT)
「ZJOI2018」历史(LCT) \(ZJOI\) 也就数据结构可做了-- 题意:给定每个点 \(access\) 次数,使轻重链切换次数最大,带修改. \(30pts:\) 挺好想的.发现切换次数 ...
- Loj #3057. 「HNOI2019」校园旅行
Loj #3057. 「HNOI2019」校园旅行 某学校的每个建筑都有一个独特的编号.一天你在校园里无聊,决定在校园内随意地漫步. 你已经在校园里呆过一段时间,对校园内每个建筑的编号非常熟悉,于是你 ...
- 「HAOI2018」染色 解题报告
「HAOI2018」染色 是个套路题.. 考虑容斥 则恰好为\(k\)个颜色恰好为\(c\)次的贡献为 \[ \binom{m}{k}\sum_{i\ge k}(-1)^{i-k}\binom{m-k ...
- 摹客iDoc「标注」新玩法!这些细节让你爱不释手(201903-2版本更新)
哈喽小伙伴们,我们又见面啦!没错,小摹就是来告诉大家:摹客iDoc又双叒叕升级了!这次又上线了许多新玩法,在此之前,小摹先带大家温习一下iDoc以往的知识点: 攻城狮查看标注的利器 —— 标注信息智能 ...
- LOJ #2585. 「APIO2018」新家
#2585. 「APIO2018」新家 https://loj.ac/problem/2585 分析: 线段树+二分. 首先看怎样数颜色,正常的时候,离线扫一遍右端点,每次只记录最右边的点,然后查询左 ...
随机推荐
- uvm_reg_block——寄存器模型(七)
这是寄存器模型的顶层 //------------------------------------------------------------------------ // Class: uvm_ ...
- Image(支持 XML 序列化),注意C#中原生的Image类是无法进行Xml序列化的
/// <summary> /// Image(支持 XML 序列化) /// </summary> [XmlRoot("XmlImage")] publi ...
- 洛谷 P2868 [USACO07DEC]观光奶牛Sightseeing Cows
题目描述 Farmer John has decided to reward his cows for their hard work by taking them on a tour of the ...
- 浅谈iOS学习之路
转眼学习iOS已经快两年的时间了,这个路上有挫折也有喜悦,一步步走过来发现这个过程是我这一辈子的财富,我以前的老大总是对我说,年轻就是最大的资本(本人91年),现在才算是慢慢的体会到,反观自己走过的这 ...
- (外挂破解)Cheat Engine(内存修改工具)V6.2中文版软件介绍
Heat Engine是一款内存修改编辑工具,Cheat Engine允许你修改你的游戏,所以你将总是赢.它包括16进制编辑,反汇编程序,内存查找工具.与同类修改工具相比,它具有强大的反汇编功能,且自 ...
- Android(java)学习笔记126:判断SD卡状态和SD卡容量
1. 判断SD卡状态和SD卡存储空间大小 当我们在使用SD卡时候,如果我们想往SD卡里读写数据,我们必须在这之前进行一个逻辑判断,那就是判断SD卡状态和SD存储空间大小: 核心代码: String s ...
- Android(java)学习笔记116:BroadcastReceiver之 静态注册 和 动态注册
1. 广播接受者>什么是广播.收音机.电台:对外发送信号.收音机:接收电台的信号. >在android系统里面,系统有很多重要的事件: 电池电量低,插入充电器,sd卡被移除,有电话打出去, ...
- JS给数字加千位分隔符
本文原链接:https://www.jianshu.com/p/928c68f92c0c JavaScript实现千位分隔符 将普通的数字转换为带千位分隔符格式的数字字符串是一个非常常见的问题,千位分 ...
- CPP-基础:类的静态成员
一 静态数据成员: 类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员.和其他数据成员一样,静态数据成员也遵守public/protected/private访问规 ...
- java基础—线程(一)
一.线程的基本概念