相当于求满足在子段中出现的颜色只在该子段中出现的非空子段数量。这也就相当于其中出现的颜色最左出现的位置在左端点右侧,最右出现的位置在右端点左侧。那么若固定某个端点,仅考虑对该端点的限制,会有一段合法区间。这个区间可以二分+st表求出。于是枚举右端点,在其合法区间内查询有多少个合法左端点(即合法区间包括该右端点),上主席树即可。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 300010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int T,n,a[N],root[N],head[N],tail[N],l[N],r[N],f[N][],lg2[N],cnt;
struct data{int l,r,x;
}tree[N<<];
int query(int l,int r)
{
if (l>r) return N;
return min(f[l][lg2[r-l+]],f[r-(<<lg2[r-l+])+][lg2[r-l+]]);
}
int query2(int l,int r)
{
if (l>r) return -;
return max(f[l][lg2[r-l+]],f[r-(<<lg2[r-l+])+][lg2[r-l+]]);
}
void ins(int &k,int l,int r,int x)
{
tree[++cnt]=tree[k],k=cnt;tree[k].x++;
if (l==r) return;
int mid=l+r>>;
if (x<=mid) ins(tree[k].l,l,mid,x);
else ins(tree[k].r,mid+,r,x);
}
int query(int x,int y,int l,int r,int p,int q)
{
if (!y) return ;
if (l==p&&r==q) return tree[y].x-tree[x].x;
int mid=l+r>>;
if (q<=mid) return query(tree[x].l,tree[y].l,l,mid,p,q);
else if (p>mid) return query(tree[x].r,tree[y].r,mid+,r,p,q);
else return query(tree[x].l,tree[y].l,l,mid,p,mid)+query(tree[x].r,tree[y].r,mid+,r,mid+,q);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj5011.in","r",stdin);
freopen("bzoj5011.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
T=read();
while (T--)
{
n=read();
for (int i=;i<=n;i++) a[i]=read(),head[i]=n+,tail[i]=;
for (int i=;i<=n;i++) head[a[i]]=min(head[a[i]],i),tail[a[i]]=max(tail[a[i]],i);
lg2[]=;
for (int i=;i<=n;i++)
{
lg2[i]=lg2[i-];
if ((<<lg2[i])<=i) lg2[i]++;
}
for (int i=;i<=n;i++) f[i][]=head[a[i]];
for (int j=;j<;j++)
for (int i=;i<=n;i++)
f[i][j]=min(f[i][j-],f[min(n,i+(<<j-))][j-]);
for (int i=;i<=n;i++)
{
int L=i-,R=n;
while (L<=R)
{
int mid=L+R>>;
if (query(i,mid)>=i) l[i]=mid,L=mid+;
else R=mid-;
}
}
for (int i=;i<=n;i++) f[i][]=tail[a[i]];
for (int j=;j<;j++)
for (int i=;i<=n;i++)
f[i][j]=max(f[i][j-],f[min(n,i+(<<j-))][j-]);
for (int i=;i<=n;i++)
{
int L=,R=i+;
while (L<=R)
{
int mid=L+R>>;
if (query2(mid,i)<=i) r[i]=mid,R=mid-;
else L=mid+;
}
}
root[]=;
for (int i=;i<=n;i++)
{
root[i]=root[i-];
ins(root[i],,n,l[i]);
}
ll ans=;
for (int i=;i<=n;i++)
ans+=query(root[r[i]-],root[i],,n,i,n);
printf(LL,ans);
}
return ;
}

BZOJ5011 JXOI2017颜色(主席树)的更多相关文章

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

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

  2. [BZOJ5011][JXOI2017]颜色

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

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

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

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

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

  5. [四校联考P3] 区间颜色众数 (主席树)

    主席树 Description 给定一个长度为 N 颜色序列A,有M个询问:每次询问一个区间里是否有一种颜色的数量超过了区间的一半,并指出是哪种颜色. Input 输入文件第一行有两个整数:N和C 输 ...

  6. 2018.07.07 洛谷 P3939 数颜色(主席树)

    P3939 数颜色 题目背景 大样例下发链接:http://pan.baidu.com/s/1c0LbQ2 密码:jigg 题目描述 小 C 的兔子不是雪白的,而是五彩缤纷的.每只兔子都有一种颜色,不 ...

  7. bzoj2120: 数颜色(BIT套主席树+set/分块)

    带修改的 HH的项链. 带修改考虑用BIT套主席树,查区间里有几个不同的数用a[i]上次出现的位置pre[i]<l的数有几个来算就好了. 考虑怎么修改.修改i的时候,我们需要改变i同颜色的后继的 ...

  8. 主席树 STL+二分【p3939】数颜色

    Description 小 C 的兔子不是雪白的,而是五彩缤纷的.每只兔子都有一种颜色,不同的兔子可能有 相同的颜色.小 C 把她标号从 \(1\) 到 \(n\) 的 \(n\) 只兔子排成长长的一 ...

  9. BZOJ2120:数颜色(数状数组套主席树)(带修改的莫对)

    墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P ...

随机推荐

  1. wpf- DataGrid 常用属性和事件

    组件所在命名空间: System.Windows.Controls 组件常用方法: BeginEdit:使DataGrid进入编辑状态. CancelEdit:取消DataGrid的编辑状态. Col ...

  2. jdk和tomcat版本对应

    见tomcat的官网说明:tomcat.apache.org/whichversion.html Apache Tomcat ®是一个开源软件实现了Java Servlet和JavaServer Pa ...

  3. 【LG4587】[FJOI2016]神秘数

    [LG4587][FJOI2016]神秘数 题面 洛谷 题解 首先我们想一想暴力怎么做 对于一段区间\([l,r]\) 我们先将它之间的数升序排序 从左往右扫, 设当前我们可以表示出的数为\([1,x ...

  4. linux挂在samba服务器到本地(用于备份文件到nas或者windows的文件服务器)

    1.安装工具 首先在linux上安装samba访问工具 sudo apt-get install smbclient sudo apt-get install cifs-utils 2.查看服务器目录 ...

  5. 【MYSQL备份】利用mysqldump将一个数据库复制到另一个数据库

    假设要将服务器A上的数据库test备份到服务器B 1.在服务器B上新建数据库cp_test mysql> create database cp_test; Query OK, row affec ...

  6. php小项目小结

    最近一直断更,并不是出于什么问题,而是想找个合适的机会去整理下html基本的一些琐碎的知识点 近期突发感冒,吊水,吊错药,原因只是重名重姓,这不是个梗,很是痛苦的现实事故 so,只能用剩下的半天去完成 ...

  7. Jenkins CLI 通过ssh方式链接时的证书

    在Jenkins自己的配置文档下,并没有详细说明要如何生成ssh证书,不过随便网上查一查就会有很多. 这里记录一个坑: 这个ssh必须要用ssh2!!! 这个ssh必须要用ssh2!!! 这个ssh必 ...

  8. python环境通过selenium实现自动化web登陆及终端邀请

    自动化主要的就是识别对象,可以在网上搜到各种各样的方法,自行百度.下面仅附上一个简单的例子. 环境搭建参考如下链接: https://www.cnblogs.com/hepeilinnow/p/101 ...

  9. hadoop 基础入门

    启动:   格式化节点:bin/hdfs namenode -format   全部启动:sbin/start-dfs:datanode.namenode                    sbi ...

  10. HttpServlet 详解(基础)

    HttpServlet详解 大家都知道Servlet,但是不一定很清楚servlet框架,这个框架是由两个Java包组成:javax.servlet和javax.servlet.http. 在java ...