\(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. Make Square CodeForces - 1028H (dp)

    大意: 若一个序列存在两个数的积为完全平方数, 则为好序列. 给定序列$a$, 每次询问求子区间$[l,r]$最少修改多少次可以成为好序列, 每次修改可以任选素数$p$, 任选一个数乘或除$p$. $ ...

  2. PHP Math常量

    常量名 常量名 常量值 PHP M_E e 2.7182818284590452354 4 M_EULER Euler 常量 0.57721566490153286061 5.2.0 M_LNPI l ...

  3. django css

    1. settings.py最下方STATIC_URL下面补上 STATIC_URL = '/home/wjg/code/wblog/static/' STATIC_ROOT = os.path.jo ...

  4. 免root xshell连接termux

    免root实现xshell连接termux termux为安卓手机上的一款模拟linux终端的应用,由于手机上打字比较麻烦,所以想到了用电脑上的xshell通过ssh连接termux,以实现电脑控制t ...

  5. robot framework 如何处理循环条件下面的变量自增

    下面举了一个基础栗子,可以运行的.${num}就是我需要的自增变量.有人也许会问为什么不用${i},不是我不想用,而是我${i}有其他用处,必须另外定义一个变量,需要注意的是定义变量的时候,应该在循环 ...

  6. 监听iframe加载完成

    用 @load="loading" 在Vue里面写了一个界面,有一个iframe标签, iframe加载其他网站, <iframe @load="loading&q ...

  7. iOS UIView视图的图层控制

    1.添加视图 insertSubview:atIndex:   //放在子视图数组的具体索引位置 insertSubview:aboveSubview:   //某个子视图前面 insertSubvi ...

  8. DbTemplate

    package com.me.dbComponent; import java.sql.Connection; import java.sql.PreparedStatement; import ja ...

  9. 互联网项目中mysql推荐(读已提交RC)的事务隔离级别

    [原创]互联网项目中mysql应该选什么事务隔离级别 Mysql为什么不和Oracle一样使用RC,而用RR 使用RC的原因 这个是有历史原因的,当然要从我们的主从复制开始讲起了!主从复制,是基于什么 ...

  10. CentOS7.X+LAMP环境下安装zabbix4.X

    1.安装zabbix仓库 rpm -ivh https://repo.zabbix.com/zabbix/4.2/rhel/7/x86_64/zabbix-release-4.2-1.el7.noar ...