E - BaoBao Loves Reading ZOJ - 4117 (树状数组求区间不同数的个数)
BaoBao is a good student who loves reading, but compared with his huge bookshelf containing lots and lots of books, his reading desk, which can only hold at most kk books, is surprisingly small.
Today BaoBao decides to read some books for nn minutes by the desk. According to his reading plan, during the ii-th minute, he is scheduled to read book a_iai. The reading desk is initially empty and all the books are initially on the shelf. If the book BaoBao decides to read is not on the desk, BaoBao will have to fetch it from the shelf. Also, if the desk is full and BaoBao has to fetch another book from the shelf, he will have to put one book back from the desk to the shelf before fetching the new book.
Tired of deciding which book to put back, BaoBao searches the Internet and discovers an algorithm called the Least Recently Used (LRU) algorithm. According to the algorithm, when BaoBao has to put a book back from the desk to the shelf, he should put back the least recently read book.
For example, let's consider the reading plan {4, 3, 4, 2, 3, 1, 4} and assume that the capacity of the desk is 3. The following table explains what BaoBao should do according to the LRU algorithm. Note that in the following table, we use a pair of integer (a, b)(a,b) to represent a book, where aa is the index of the book, and bb is the last time when this book is read.
Minute | Books on the Desk Before This Minute | BaoBao's Action |
---|---|---|
1 | {} | Fetch book 4 from the shelf |
2 | {(4, 1)} | Fetch book 3 from the shelf |
3 | {(4, 1), (3, 2)} | Do nothing as book 4 is already on the desk |
4 | {(4, 3), (3, 2)} | Fetch book 2 from the shelf |
5 | {(4, 3), (3, 2), (2, 4)} | Do nothing as book 3 is already on the desk |
6 | {(4, 3), (3, 5), (2, 4)} | Put book 4 back to the shelf as its the least recently read book, and fetch book 1 from the shelf |
7 | {(3, 5), (2, 4), (1, 6)} | Put book 2 back to the shelf as its the least recently read book, and fetch book 4 from the shelf |
Given the reading plan, what's the number of times BaoBao fetches a book from the shelf if the value of kk (the capacity of the desk) ranges from 1 to nn (both inclusive)?
Input
There are multiple test cases. The first line of the input contains an integer TT, indicating the number of test cases. For each test case:
The first line contains an integer nn (1 \le n \le 10^51≤n≤105), indicating the length of the reading plan.
The second line contains nn integers a_1, a_2, \dots, a_na1,a2,…,an (1 \le a_i \le n1≤ai≤n), indicating the indices of the books to read.
It's guaranteed that the sum of nn of all test cases will not exceed 10^6106.
Output
For each test case output one line containing nn integers f_1, f_2, \dots, f_nf1,f2,…,fn separated by a space, where f_ifi indicates the number of times BaoBao fetches a book from the shelf when the capacity of the desk is ii.
Please, DO NOT output extra spaces at the end of each line, or your solution may be considered incorrect!
Sample Input
1 7 4 3 4 2 3 1 4
Sample Output
7 6 5 4 4 4 4
#include<map> #include<set> #include<cmath> #include<deque> #include<queue> #include<stack> #include<string> #include<bitset> #include<cstdio> #include<vector> #include<iomanip> #include<cstring> #include<sstream> #include<iostream> #include<algorithm> //#include<bits/stdc++.h> #define P pair<ll, ll> #define pi acos(-1) #define fi first #define se second #define ll long long #define pb push_back #define eps 1e-10 #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define maxn 400050 #define lson l,mid,rt*2 #define rson mid+1,r,rt*2+1 #define lowbit(x) (x&(-x)) #define SZ(x) ((int)(x).size()) #define met(a,x) memset(a,x,sizeof(a)) #define openin(x) freopen(x, "r", stdin) #define openout(x) freopen(x, "w",stdout) #define rep(i,a,b) for(ll i = a;i <= b;i++) #define bep(i,a,b) for(ll i = a;i >= b;i--) #define ios() ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b,a%b); } ll lcm(ll a, ll b) { return a * b / gcd(a, b); } const ll mod = 998244353; using namespace std; inline ll read() { ll x = 0; char ch = getchar(); for (; !isdigit(ch); ch = getchar()); for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0'; return x; } ll a[maxn], last[maxn], c[maxn],dp[maxn]; int n; void update(int pos, int x) { for (int i = pos; i <= n; i += lowbit(i)) { c[i] += x; } } ll sum(ll pos) { ll ans = 0; for (int i = pos; i >= 1; i -= lowbit(i)) { ans += c[i]; } return ans; } int main() { int T = read(); while (T--) { n = read(); rep(i, 1, n)last[i] = -1,dp[i] = c[i] = 0; rep(i, 1, n) { a[i] = read(); if (last[a[i]] == -1) { last[a[i]] = i; update(i, 1); } else { update(last[a[i]], -1); update(i, 1); ll now = sum(i) - sum(last[a[i]]-1); dp[now]++; last[a[i]] = i; } } ll ans = 0; rep(i, 1, n) { dp[i] += dp[i - 1]; if (i == 1)cout << n - dp[i]; else cout << ' ' << n - dp[i]; } cout << endl; } getchar(); getchar(); return 0; }