其他分享
首页 > 其他分享> > 洛谷P1972HH的项链 题解

洛谷P1972HH的项链 题解

作者:互联网

题目描述

HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此,他的项链变得越来越长。

有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答…… 因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。

题目分析

这个问题是一个区间求值的问题,数据范围辣么大,自然而然的想到利用前缀和的思想

BUT 这道题并不是简单的区间和,而是区间内所有数值的种类数

也就是说,一段区间内重复的元素只有其中一个对答案的贡献为 \(1\),其他所有都不做贡献

那么我们就从每种相同的元素选出一个代表,代表做出 \(1\) 的贡献,而其他元素都不做贡献不就行了?
(说起来容易,到底怎么做呀!)

那我们到底选 哪一位幸运观众 哪一个数来当我们的代表元素哩?

是第一个?第二个?最后一个?还是都可以?

答案是:(刮刮乐——>)最后一个

为什么是最后一个呢?

别急,听我仔细向您道来~

如果我们不选一段区间里的重复元素中的最后一个作为代表元素

那么,如果正好有一段区间,只包含这些元素中的最后那一个,答案本应该加上 \(1\),但我们却加不上,因为那 \(1\) 的贡献在别人身上

所以我们应该把所有重复元素贡献集中到最后一个
当然不是全部的最后一个,是会随着从左到右考虑而变化的

之后,我们就有了如下思路:

(输入量巨大,记得加快读快出)

思路分析完毕,上代码:

AC代码

#include<iostream>
#include<algorithm>

using namespace std;

const int N=1e6+10;

int n,m;
int c[N];
int l[N],o[N];
int a[N];

void read(int& x)
{
	x=0;
	int f=1;
	char c;
	c=getchar();
	while(c<'0'||c>'9')
	{
		if(c=='-')
			f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		x=x*10+c-'0';
		c=getchar();
	}
	x*=f;
}

void write(int x)
{
	if(x<0)
	{
		putchar('-');
		x=-x;
	}
	if(x>9)
		write(x/10);
	putchar(x%10+'0');
}

struct Q{
	int l,r;
	int id;
}q[N];

int lowbit(int x)
{
	return x&-x;
}

void update(int x,int k)
{
	while(x<=n)
	{
		c[x]+=k;
		x+=lowbit(x);
	}
}

int query(int x)
{
	int res=0;
	while(x)
	{
		res+=c[x];
		x-=lowbit(x);
	}
	return res;
}

bool cmp(Q A,Q B)
{
	return A.r<B.r;
}

int main()
{
	read(n);
	for(int i=1;i<=n;i++)
	{
		int x;
		read(x);
		o[i]=l[x];
		l[x]=i;
	}
	read(m);
	for(int i=1;i<=m;i++)
	{
		read(q[i].l),read(q[i].r);
		q[i].id=i;
	}
	sort(q+1,q+m+1,cmp);
	int p=1;
	for(int i=1;i<=n;i++)
	{
		if(o[i])
			update(o[i],-1);
		update(i,1);
		while(i==q[p].r)
		{
			a[q[p].id]=query(q[p].r)-query(q[p].l-1);
			p++;
		}
	}
	for(int i=1;i<=m;i++)
		write(a[i]),puts("");
	
	return 0;
}

完结撒花?

不,还没有完全结束

我们刚才证明了把贡献放在除了最后一个的其他位置不能得到这道题的答案

那他能得到什么题的答案呢?

刚才把代表元素定位最后一个,就可以得到区间内出现次数大于等于一的数的种类

那如果我们选倒数第二个,是不是就可以得到区间内出现次数大于等于二的数的种类

聪明!当然可以!

补充完这一点,这题就彻底做完了

白白ヾ(•ω•`)o~~~

标签:洛谷,贝壳,P1972HH,int,题解,元素,贡献,项链,区间
来源: https://www.cnblogs.com/Orange-Star/p/16593354.html