uva 12345 Dynamic len(set(a[L:R]))

Description

Download as PDF

K

Dyanmic len(set(a[L:R]))

Input: Standard Input

Output: Standard Output

 

In python, we can use len(start(a[L:R])) to calculate the number of distinct values of elements a[L], a[L+1], ..., a[R-1].

 

Here are some interactive examples that may help you understand how it is done. Remember that the indices of python lists start from 0.

 

>>> a=[1,2,1,3,2,1,4]

>>> print a[1:6]

[2, 1, 3, 2, 1]

>>> print set(a[1:6])

set([1, 2, 3])

>>> print len(set(a[1:6]))

3

>>> a[3]=2

>>> print len(set(a[1:6]))

2

>>> print len(set(a[3:5]))

1

 

Your task is to simulate this process.

 

Input

There will be only one test case. The first line contains two integers n and m (1 ≤ n,m ≤ 50,000). The next line contains the original list.

 

All the integers are between 1 and 1,000,000 (inclusive). The next m lines contain the statements that you need to execute.

 

A line formatted as "M x y" (1 ≤ y ≤ 1,000,000) means "a[x] = y", and a line formatted as "Q x y" means "print len(set(a[x:y]))".

 

It is guaranteed that the statements will not cause "index out of range" error.

 

Output

Print the simulated result, one line for each query.

 

Sample Input                               Output for Sample Input

7 4

1 2 1 3 2 1 4

Q 1 6

M 3 2

Q 1 6

Q 3 5

 

3

2

1

 


 

 解析

这个题我是暴力的,不要用set,set是O(nlogn)会T,用hash也不要每次查询memset。

其实标算是这个,不过完全没看懂。

常见到一类问题,求[L,R]之间在[u,v]上的元素的个数,或者元素和之类的问题,这样的问题归结于二维树状数组,但是当规模很大的时候,我们不能开那么多的空间来存放,这时候我们要考虑用树状数组维护[L,R]这一维,然后对于树状数组的每一个结点,用一个BST来存这个结点区间内的全部数字,这样对于一个结点查询[u,v]是O(logN)的,树状数组这一维是O(logN)的,可以在O(logNlogN)时间内得到结果。

#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;

int a[50100],N,M,list[1000100];
void Ask(int l,int r)
{
	int ans=0;
	for(int i=l;i<r;i++)
	{
		if(!list[a[i]])ans++;
		list[a[i]]++;
	}
	printf("%d\n",ans);
	for(int i=l;i<r;i++) list[a[i]]--;
}

int main()
{
	scanf("%d%d",&N,&M);
	for(int i=0;i<N;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=M;i++)
	{
		char c; scanf("\n%c",&c);
		if(c=='M') {int x;scanf("%d",&x);scanf("%d",&a[x]);}
		if(c=='Q') {int l,r;scanf("%d%d",&l,&r);Ask(l,r);}
	}
	while(1);
	return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值