\(Orz\) 各位题解大佬,我来膜拜一发

还有单调栈实在没弄懂

法一:线段树+堆

首先,讨论区间的个数的题目,我们可以想到枚举一个端点\(r\),找到所有的\(l\)

我们不妨设:\(ml[i]\)为第i种颜色出现的最小位置,\(mr[i]\)为第i种出现的最大位置

我们想到对于一个右端点,他有那些值是不能选的:

假设有一种颜色的\(mr\)值比当前枚举的右端点小,则\([ml, mr]\)里面的所有的左端点都不能选,对应到线段树中就是区间赋成0

再假设有一种颜色,当前枚举的右端点在\([ml[i], mr[i]]\)之间,那么我们记录一个\(last[i]\),表示小于当前右端点的最大的i

那么\([1, last[i]]\)所有的值都不能选

然后我们要找到一个最大的last,用一个堆即可

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define re register
#define int long long
il int read() {
re int x = 0, f = 1; re char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
return x * f;
}
#define rep(i, s, t) for(re int i = s; i <= t; ++ i)
#define mem(k, p) memset(k, p, sizeof(k))
#define ls k * 2
#define rs k * 2 + 1
#define maxn 300005
int n, m, a[maxn], last[maxn], ans, ml[maxn], mr[maxn], tag[maxn << 2], sum[maxn << 2];
struct node {int id, val; il bool operator < (const node&x) const{return val < x.val;}};
priority_queue<node> q;
il void pushdown(int k, int l, int r, int mid) {
if(tag[k] == -1) return;
sum[ls] = (mid - l + 1) * tag[k], sum[rs] = (r - mid) * tag[k];
tag[ls] = tag[rs] = tag[k]; tag[k] = -1;
}
il void modify(int k, int l, int r, int ll, int rr, int x) {
if(l > rr || ll > r) return;
if(ll <= l && r <= rr) return (void)(tag[k] = x, sum[k] = (r - l + 1) * x);
int mid = (l + r) >> 1; pushdown(k, l, r, mid);
modify(ls, l, mid, ll, rr, x), modify(rs, mid + 1, r, ll, rr, x);
sum[k] = sum[ls] + sum[rs];
}
il int query(int k, int l, int r, int ll, int rr) {
if(l > rr || ll > r) return 0;
if(ll <= l && r <= rr) return sum[k];
int mid = (l + r) >> 1; pushdown(k, l, r, mid);
return query(ls, l, mid, ll, rr) + query(rs, mid + 1, r, ll, rr);
}
il void solve() {
n = read(), ans = 0, mem(tag, -1), modify(1, 1, n, 1, n, 1);
while(!q.empty()) q.pop();
rep(i, 1, n) ml[i] = n + 1, mr[i] = last[i] = 0;
rep(i, 1, n) a[i] = read(), ml[a[i]] = min(ml[a[i]], i), mr[a[i]] = max(mr[a[i]], i);
rep(i, 1, n) {
last[a[i]] = i, q.push((node){a[i], last[a[i]]});
if(i == mr[a[i]]) modify(1, 1, n, ml[a[i]] + 1, mr[a[i]], 0);
while(!q.empty()) {
int x = q.top().id;
if(last[x] == mr[x]) q.pop();
else break;
}
int pax = (q.empty() ? 1 : q.top().val + 1);
ans += query(1, 1, n, pax, i);
}
printf("%lld\n", ans);
}
signed main() {
int T = read();
while(T --) solve();
return 0;
}

随机化

对于每一个位置,我们需要随机一个值,然后需要保证相同的颜色的所有的随机值异或结果为\(0\)

由于异或满足$a\ \(^\)\ b = 0$,所以我们把每个颜色的除了最后一项的所有随机值异或起来,让最后一位等于这个随机值

然后我们不难发现,每一个满足条件的一段区间,他的异或的值显然是等于0的

所以问题就转化成了:有多少区间的异或和等于0

由于上述异或的性质,于是我们只需要用\(map\)存一下即可

跟据@\(Ebola\)大佬的证明,我们的错误率是很小的。

\(Code:\)

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define re register
#define debug printf("Now is Line : %d\n",__LINE__)
#define file(a) freopen(#a".in","r",stdin);freopen(#a".out","w",stdout)
#define int long long
il int read() {
re int x = 0, f = 1; re char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
return x * f;
}
#define rep(i, s, t) for(re int i = s; i <= t; ++ i)
#define drep(i, s, t) for(re int i = t; i >= s; -- i)
#define Next(i, u) for(re int i = head[u]; i; i = e[i].next)
#define mem(k, p) memset(k, p, sizeof(k))
#define lb(x) (x)&(-(x))
#define ls k * 2
#define rs k * 2 + 1
#define maxn 300005
int n, m, a[maxn], val[maxn];
vector<int>q[maxn];
map<int, int> p;
il int Random() {
return 1ll * rand() * rand() * rand();
}
signed main() {
srand(time(0));
int T = read();
while(T --) {
n = read();
rep(i, 1, n) a[i] = read(), q[a[i]].push_back(i), val[i] = 0;
rep(i, 1, n) {
int sum = 0;
for(re int j = 0; j < q[i].size(); ++ j) {
if(j == q[i].size() - 1) val[q[i][j]] = sum;
else sum ^= (val[q[i][j]] = Random());
}
q[i].clear();
}
int ans = 0, now = 0; p[0] = 1;
rep(i, 1, n) now ^= val[i], ans += p[now], ++ p[now];
rep(i, 1, n) now ^= val[i], p[now] = 0;
printf("%lld\n", ans);
}
return 0;
}

[JXOI2017]颜色的更多相关文章

  1. JXOI2017颜色 解题报告

    JXOI2017颜色 首先记录每个位置上颜色在序列中上次出现的位置 开两颗线段树,第一棵维护区间最大值,实际上是维护当前必须被删去的颜色的位置的最大值,第二棵则是维护区间和 首先倒着扫一遍,对于当前颜 ...

  2. [JXOI2017]颜色 线段树求点对贡献

    [JXOI2017]颜色 题目链接 https://www.luogu.org/problemnew/show/P4065 题目描述 可怜有一个长度为 n 的正整数序列 Ai,其中相同的正整数代表着相 ...

  3. [BZOJ5011][JXOI2017]颜色

    5011: [Jx2017]颜色 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 84  Solved: 46[Submit][Status][Disc ...

  4. 洛谷P4065 [JXOI2017]颜色(线段树)

    题意 题目链接 Sol 线段树板子题都做不出来,真是越来越菜了.. 根据题目描述,一个合法区间等价于在区间内的颜色没有在区间外出现过. 所以我们可以对于每个右端点,统计最长的左端点在哪里,刚开始以为这 ...

  5. JXOI2017颜色

    题面 loj 分析 这道题非常妙啊 对于可保留区间[l, r] 枚举右端点r 考虑l的取值范围有两重约数 记颜色i出现的最右侧位置是\(max_i\) 最左侧位置是\(min_i\) r前最后一次出现 ...

  6. BZOJ5011 JXOI2017颜色(主席树)

    相当于求满足在子段中出现的颜色只在该子段中出现的非空子段数量.这也就相当于其中出现的颜色最左出现的位置在左端点右侧,最右出现的位置在右端点左侧.那么若固定某个端点,仅考虑对该端点的限制,会有一段合法区 ...

  7. 【题解】JXOI2017颜色

    一眼线段树...显然,我们可以考虑最后所留下的区间,那显然这个区间中应当不能存在任何与区间外相同的颜色.这里的转化也是很常用的,我们用 \(nxt[i]\) 表示与 \(i\) 颜色相同的下一个位置在 ...

  8. [JXOI2017]颜色 线段树扫描线 + 单调栈

    ---题面--- 题解: 首先题目要求删除一些颜色,换个说法就是要求保留一些颜色,那么观察到,如果我们设ll[i]和rr[i]分别表示颜色i出现的最左边的那个点和最右边的那个点,那么题目就是在要求我们 ...

  9. BZOJ5011 & 洛谷4065 & LOJ2275:[JXOI2017]颜色——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5011 https://www.luogu.org/problemnew/show/P4065 ht ...

  10. BZOJ5011 [JXOI2017]颜色 【线段树 + 主席树】

    题目链接 BZOJ5011 题解 一定只有我这种智障会用这么奇怪的方法做这道题.. 由题我们知道最后剩余的一定是一个区间,而且区间内的颜色不存在于区间外 所以我们的目的就是为了找到这样的区间的数量 区 ...

随机推荐

  1. 『Python基础练习题』day04

    # 1.写代码,有如下列表,按照要求实现每一个功能 # li = ['Conan', 'Kidd', 'blame', 'jimmy', 'RachelMoore'] # 计算列表的长度并输出 # 列 ...

  2. 第二次用map23333

    度熊所居住的 D 国,是一个完全尊重人权的国度.以至于这个国家的所有人命名自己的名字都非常奇怪.一个人的名字由若干个字符组成,同样的,这些字符的全排列的结果中的每一个字符串,也都是这个人的名字.例如, ...

  3. java 读取文件流

    搬运自速学堂:https://www.sxt.cn/Java_jQuery_in_action/ten-iqtechnology.html JAVA中IO流体系: 四大IO抽象类 ·InputStre ...

  4. ELK搜索条件

    1.要搜索一个确切的字符串,即精确搜索,需要使用双引号引起来:path:”/app/logs/nginx/access.log” 2.如果不带引号,将会匹配每个单词:uid token 3.模糊搜索: ...

  5. 【SoloPi】SoloPi使用4-功能使用,一机多控

    Soloπ是什么Soloπ是一个无线化.非侵入式的Android自动化工具,公测版拥有录制回放.性能测试.一机多控三项主要功能,能为测试开发人员节省宝贵时间. 一机多控功能Soloπ支持通过操作一台主 ...

  6. C# mailKit 发邮件 简单代码

    public static async Task<bool> SendMailAsync22(string Name, string receive, string sender, str ...

  7. 伪静态 net-IIS伪静态配置,使用URLRewriter实现伪静态

    https://www.cnblogs.com/zhenzaizai/p/10364343.html 前段时间开发公司官网,用到了URLRewriter实现伪静态,在VS调试模式下没有任何问题,部署到 ...

  8. Go 关于 kafka 的生产者、消费者实例

    zookeeper + kafka 首先要在 apche 官网下载 kafka 的程序包(linux版本),然后放到服务器上解压,得到以下目录 bin 目录下包含了服务的启动脚本 启动 zookeep ...

  9. iOS - 苹果官方Apple Pay开发文档(中文版)- Apple Pay(1)

    翻译自苹果官方Apple Pay开发文档.目前版本为1.0 概览: Apple Pay为用户从你的App里购买实际的物品和服务提供简单而安全的方法.通过Touch ID,用户可使用储存在iPhone ...

  10. SAP Marketing Cloud功能简述(二) : Target Group

    这个系列的第一篇文章 SAP Marketing Cloud功能简述(一) : Contacts和Profiles,我向大家介绍了SAP Marketing Cloud里的Contacts和Profi ...