# Different Integers

### 题目描述

Given a sequence of integers a1, a2, ..., an and q pairs of integers (l1, r1), (l2, r2), ..., (lq, rq), find count(l1, r1), count(l2, r2), ..., count(lq, rq) where count(i, j) is the number of different integers among a 1, a2, ..., ai, aj, aj + 1, ..., an.

### 输入描述：

The input consists of several test cases and is terminated by end-of-file. The first line of each test cases contains two integers n and q. The second line contains n integers a1, a2, ..., an. The i-th of the following q lines contains two integers li and ri.

### 输出描述：

For each test case, print q integers which denote the result.

### 备注

* 1 ≤ n, q ≤ 105

* 1 ≤ ai ≤ n

* 1 ≤ li, ri ≤ n

* The number of test cases does not exceed 10.

3 2

1 2 1

1 2

1 3

4 1

1 2 3 4

1 3

2

1

3

# 解法

#include<iostream>
#include<vector>
using namespace std;
int main()
{
//取消cin与stdin的同步
ios::sync_with_stdio(false);
int n, q, num;
int r[10];
vector<int>res;
while (cin >> n >> q)
{
//二维vector数组，存放首位置和末位置
vector<vector<int>> v(n);
int k = 1;
for (int i = 0; i < n; i++)
{
cin >> num;
//向数组中加入位置
v[num - 1].push_back(k++);
}
int left, right, sum = 0;
for (int e = 0; e < q; e++)
{
sum = 0;
cin >> left >> right;
for (int i = 0; i < n; i++)
{
//如果数组为空 continue
if (!v[i].size())
continue;
//如果首位置<left||末位置>right 个数++
if (v[i][0] <= left || v[i].back() >= right)
sum++;
}
//将个数加入数组中
res.push_back(sum);
}
}
//遍历输出
for (auto i : res)
cout << i << endl;
//system("pause");
}


#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
//用于存储左边界值和右边界值，id号
struct Region
{
int left, right, id;
};

//重载运算符 < ， 依据右边界升序
bool operator < (const Region& u, const Region& v)
{
return u.right < v.right;
}

int main()
{
int n, q;
while (cin >> n >> q)
{
vector<int> a(n), first(n, -1), last(n), count(n), result(q);
int total = 0;
for (int i = 0; i < n; ++i)
{
cin >> a[i];
a[i] --;
//记录元素最后出现的位置
last[a[i]] = i;
//如果元素之前未出现 则记录第一次出现的位置
if (first[a[i]] == -1)
{
total++;
first[a[i]] = i;
}
}
vector<Region> regions;
for (int i = 0, l, r; i < q; ++i)
{
cin >> l >> r;
//将区间和id加到容器中
regions.push_back(Region{ l - 1, r - 1, i });
}
//以区间的右边界 升序排序
sort(regions.begin(), regions.end());
for (int i = 0, k = 0; i < n; ++i)
{
/*==================================================================
树状数组维护
记录维护区间的次数k && 此区间右边界之前的区域全部维护完成后进入循环
===================================================================*/
while (k < q && regions[k].right == i)
{
//将result数组初始化为数列中不同元素的个数
//res引用
int& res = result[regions[k].id] = total;
/*===================================================
总数- 从该区间左边界至右边界，所有不出现的元素的个数
~j & j+1 +的优先级比&高
=====================================================*/
for (int j = regions[k].left; j < i; j += ~j & j + 1)
res -= count[j];
k++;
}
if (last[a[i]] == i)
{
/*===================================================
在该元素左端点以前都没有出现该元素
count数组用于统计没有出现的元素个数
====================================================*/
for (int j = first[a[i]] - 1; ~j; j -= ~j & j + 1)
count[j] ++;
}
}
for (auto i : result)
cout << i << endl;
}
//system("pause");
}