Time Limit: 4 Sec Memory Limit: 64 MB
Submit: 4677 Solved: 2318
Description
HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一
段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此他的项链变得越来越长。有一天,他突然提出了一
个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只
好求助睿智的你,来解决这个问题。
Input
第一行:一个整数N,表示项链的长度。
第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。
第三行:一个整数M,表示HH询问的个数。
接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
N ≤ 50000,M ≤ 200000。
Output
M行,每行一个整数,依次表示询问对应的答案。
Sample Input
6
1 2 3 4 3 5
3
1 2
3 5
2 6
Sample Output
2
2
4
HINT
Source
Day2
题解:和我写的BZOJ 2743 其实是一道题,我们还是维护nxt数组和lst数组,然后每次利用这两个数组的性质,进行修改即可
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n, m, maxn, lst[1000005], a[50005], nxt[50005], C[50005], ans[200005];
struct Q { int l, r, id; }q[200005];
bool cmp( const Q &a, const Q &b ) { return a.l < b.l; }
void modify( int x, int v ) { for( ; x <= n; x += x & (-x) ) C[x] += v; }
int query( int x ) { int tmp = 0; for( ; x; x -= x & (-x) ) tmp += C[x]; return tmp; }
int main( ) {
scanf( "%d", &n );
for( register int i = 1; i <= n; i++ ) scanf( "%d", &a[i] ), maxn = max( a[i], maxn );
for( register int i = n; i > 0; i-- ) nxt[i] = lst[a[i]], lst[a[i]] = i;
for( register int i = 1; i <= maxn; i++ ) if(lst[i]) modify( lst[i], 1 );
scanf( "%d", &m );
for( register int i = 1; i <= m; i++ ) scanf( "%d%d", &q[i].l, &q[i].r ), q[i].id = i;
sort( q + 1, q + m + 1, cmp );
int l = 1;
for( register int i = 1; i <= m; i++ ) {
while( l < q[i].l ) {
if( nxt[l] ) modify( nxt[l], 1 );
l++;
}
ans[q[i].id] = query( q[i].r )- query( q[i].l - 1 );
}
for( register int i = 1; i <= m; i++ ) printf( "%d\n", ans[i] );
return 0;
}