http://www.elijahqi.win/archives/1505
题目背景
2017.11.8
leoly选讲题
题目描述
玩具店新开张,免费赠送一些彩色弹珠,小明决定来蹭这个便宜。
玩具店老板将
n
n个弹珠排成了一排,第
i
i个弹珠有一个颜色
c_i
ci。小明只能从这排弹珠里选取一个区间,拿到其中仅出现了该颜色一次的弹珠。
小明想知道他最多可以拿走几颗弹珠。
输入输出格式
输入格式:
第一行一个正整数
n
n,表示有
n
n个弹珠。第二行
n
n个数用空格隔开,第
i
i个数表示弹珠颜色
c_i
ci。
输出格式:
一个数,表示小明最多能拿走的弹珠数量。
输入输出样例
输入样例#1: 复制
10
1 2 3 6 6 3 7 9 8 8
输出样例#1: 复制
5
说明
对于
30\%
30%的数据:
n \leq 1000
n≤1000。
对于
100\%
100%的数据:
n \leq 300000
n≤300000,
1 \leq c_i \leq n
1≤ci≤n。
时间限制:
1000ms
1000ms。
内存限制:
256MB
256MB。
预处理出每个点的前缀&后缀
那么在他们的前缀和后缀之间的就是都可以取的
所以我们认为可以构造这样一个区间 左端点属于pre[i]+1~i 右端点属于i~last[i]-1 这样的区间 都可以享受到来自a[i]的加成
那么我们可以利用之前扫面线一样 我们把区间的两个端点看做平面上的点
然后相当于每次一个矩形 然后求问 平面内 哪个点被矩形覆盖的次数最多 求出这个次数是多少即可 相当于差不多是询问离线 然后线段树维护即可
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 330000
#define inf 0x7f7f7f7f
inline char gc(){
static char now[1<<16],*S,*T;
if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
inline int