生活随笔
收集整理的這篇文章主要介紹了
牛客网暑期ACM多校训练营(第一场)J Different Integers
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接
題意
長度為N的數組,Q次詢問,每次詢問給兩個數 L,R,求區間 [1, L] 和 [R, N]中一共有幾種數
1 <= N, Q <= 1e5
每次最多10個測試數據
AC
- 暴力肯定超時,用樹狀數組維護
離線考慮沒出現的數字個數假設 r > last[x],那么當l < first[x] 時,則x 沒出現
有兩種實現方式:
- 按照查詢區間的右端點升序
當數字最后出現在這個右端點處,那么下面的區間的右側至少不會出現這個數字,因為下個區間的右端點大于等于上個區間,只用判斷左區間就ok - 按照查詢區間的左端點降序
當數字第一次出現在左端點處,那么下一個區間的左側至少不會出現這個數字,因為下個區間的左端點小于上個區間,只用判斷右區間就ok - 左端點降序
using namespace std;
struct ac{
int l, r, id;
bool operator <(
const ac &x) {
return l > x.l;}
};
int main() {
#ifndef ONLINE_JUDGEfreopen(
"in.txt",
"r", stdin);
#endifint n, q;
while (
scanf(
"%d%d", &n, &q) != EOF) {
vector<int> a(n +
1), first(n +
1), last(n +
1);
int sum =
0;
for (
int i =
1; i <= n; ++i) {
scanf(
"%d", &a[i]);last[a[i]] = i;
if (!first[a[i]])first[a[i]] = i, sum++;}
vector<ac> queries(q);
for (
int i =
0; i < q; ++i) {
scanf(
"%d%d", &queries[i].l, &queries[i].r);queries[i].id = i;}sort(queries.begin(), queries.end());
vector<int> count(n +
1), ans(q);
for (
int i = n, k =
0; i >=
1; --i) {
while (k < q && queries[k].l == i) {
if (k == q)
break;ans[queries[k].id] = sum;
for (
int j = queries[k].r; j >
0; j -= lowbit(j)) {ans[queries[k].id] -= count[j];}k++;}
if (first[a[i]] == i) {
for (
int j = last[a[i]] +
1; j <= n; j += lowbit(j)) {count[j]++;}}}
for (
int i =
0; i < q; ++i) {
printf(
"%d\n", ans[i]);}}
return 0;
}
using namespace std;
struct ac{
int l, r, id;
bool operator <(
const ac &a) {
return r < a.r;}
};
int main(){
#ifndef ONLINE_JUDGEfreopen(
"in.txt",
"r", stdin);
#endifint n, q;
while (~
scanf(
"%d%d", &n, &q)) {
vector<int> a(n +
1), last(n +
1), first(n +
1);
int sum =
0;
for (
int i =
1; i <= n; ++i) {
scanf(
"%d", &a[i]);last[a[i]] = i;
if (!first[a[i]]) {first[a[i]] = i;sum++;}}
vector<int> count(n +
1), ans(q);
vector<ac> queries(q);
for (
int i =
0; i < q; ++i) {
scanf(
"%d%d", &queries[i].l, &queries[i].r);queries[i].id = i;}sort(queries.begin(), queries.end());
int k =
0;
for (
int i =
1; i <= n && k < q; ++i) {
while (k < q && queries[k].r == i) {ans[queries[k].id] = sum;
for (
int j = queries[k].l; j <= queries[k].r; j += lowbit(j)) {ans[queries[k].id] -= count[j];}++k;}
if (last[a[i]] == i) {
for (
int j = first[a[i]] -
1; j >
0; j -= lowbit(j)) {count[j]++;}}}
for (
int i =
0 ; i < q; ++i) {
printf(
"%d\n", ans[i]);}}
總結
以上是生活随笔為你收集整理的牛客网暑期ACM多校训练营(第一场)J Different Integers的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。