题意:
给定一个长5w静态的序列,询问20w次,每次询问查找一个区间内的元素种类数
染色问题神烦啊,最近刚会做,感觉都可以用统一的方法
首先要算出与一个元素相同的最邻近的上一个元素的位置,这样的话只要求出区间内上一位置小于下限的就是元素种类数
——非常有道理的样子,但是第一次见肯定想不到
于是实现了 颜色种类问题->范围内数的个数 的问题转化
然后就简单了,交给权值主席树就好了
算是第二道主席树练习题吧
深井冰错误:构造权值线段树的时候忘记把0构造进去,MDZZ
#include <cstdio>
#define mid (l+r)/2
struct node{int size,ls,rs;} t[];
int cnt=,n,m,x,y,a[],p[],c[],root[];
int add(int now,int l,int r,int x)
{
int po=++cnt;
t[po]=(node){t[now].size+,(l<r && x<=mid)?add(t[now].ls,l,mid,x):t[now].ls,(l<r && x>mid)?add(t[now].rs,mid+,r,x):t[now].rs};
return po;
}
int que(int x,int y,int l,int r,int z)
{
if(l==r) return t[y].size-t[x].size;
return (z<=mid)?que(t[x].ls,t[y].ls,l,mid,z):t[t[y].ls].size-t[t[x].ls].size+que(t[x].rs,t[y].rs,mid+,r,z);
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]),p[i]=c[a[i]],c[a[i]]=i,root[i]=add(root[i-],,n,p[i]);
scanf("%d",&m);
for(int i=;i<=m;i++)
scanf("%d%d",&x,&y),printf("%d\n",que(root[x-],root[y],,n,x-));
return ;
}
老板娘你还我代码风格!!!