HH necklace HYSBZ - 1878 (Mo Team / Fenwick tree)

HH string necklace from a variety of beautiful shells composed. HH believe different shells to bring good luck, so after every walk, he will be free to remove a

Segment shells, ponder the meaning they express. HH constantly collecting new shell, so he's getting longer necklace. One day, he suddenly proposed a

Problem: a certain period of shells, including how many different shells? This question is difficult to answer. . . Because the necklace is too long. So he just

Good wise help you to solve this problem.

Input

The first line: an integer N, the length of the necklace.

Second line: N integers representing sequentially represents necklace shell (numbering is an integer between 0 and 1000000).

Third row: an integer M, represents the number HH inquiry.

Next M rows: each row two integers, L and R (1 ≤ L ≤ R ≤ N), representing the interval inquiry.

N ≤ 50000,M ≤ 200000。

Output

M lines, each an integer, respectively for the corresponding answer inquiries.

Sample Input

6 1 2 3 4 3 5 3 1 2 3 5 2 6

Sample Output

2 2 4

Hint

Ideas:

1, with Mo team, then that is a template problem.

2, with the array off the tree, we will ask the interval L sorted in ascending order, and then in the array, the number of each of a [i] a record Next [i] represent this number appears again in the right index.

Then maintain a current index L = 1 start, you can update Fenwick tree.

Mo Team Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2) { ans = ans * a % MOD; } a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int *p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
ll ans[maxn];
ll Ans = 0ll;
int l = 0;
int r = 0;
int b[maxn];
int vis[maxn];
struct node {
    int l, r, id;
} a[maxn];
int pos[maxn];
int n, m;
int len;
bool cmp(node aa, node bb)
{
    if (pos[aa.l] == pos[bb.l]) {
        return aa.r < bb.r;
    } else {
        return pos[aa.l] < pos[bb.l];
    }
}
void add(int x)
{
    if (!vis[x]) {
        Ans++;
    }
    vis[x]++;
}
void del(int x)
{
    if (vis[x] == 1) {
        Ans--;
    }
    vis[x]--;
}
int main()
{
    //freopen("D:\\code\\text\\input.txt","r",stdin);
    //freopen("D:\\code\\text\\output.txt","w",stdout);
    gg(n);
    len = (int)(sqrt(n));
    repd(i, 1, n) {
        gg(b[i]);
    }
    gg(m);
    repd(i, 1, m) {
        gg(a[i].l);
        gg(a[i].r);
        a[i].id = i;
        pos[i] = i / len;
    }
    sort(a + 1, a + 1 + m, cmp);
    repd(i, 1, m) {
        while (l > a[i].l) {
            l--;
            add(b[l]);
        }
        while (r < a[i].r) {
            r++;
            add(b[r]);
        }
        while (l < a[i].l) {
            del(b[l]);
            l++;
        }
        while (r > a[i].r) {
            del(b[r]);
            r--;
        }
        ans[a[i].id] = Ans;
    }
    repd(i, 1, m) {
        printf("%lld\n", ans[i]);
    }
    return 0;
}

inline void getInt(int *p)
{
    char ch;
    do {
        ch = getchar();
    } while (ch == ' ' || ch == '\n');
    if (ch == '-') {
        *p = -(getchar() - '0');
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 - ch + '0';
        }
    } else {
        *p = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 + ch - '0';
        }
    }
}


Stump array of code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2) { ans = ans * a % MOD; } a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int *p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int tree[maxn];
int lowbit(int x)
{
    return -x & x;
}
int n, m;
void add(int x, int val)
{
    while (x <= n) {
        tree[x] += val;
        x += lowbit(x);
    }
}
int ask(int x)
{
    int res = 0;
    while (x) {
        res += tree[x];
        x -= lowbit(x);
    }
    return res;
}
struct node {
    int l, r, ans, id;
} b[maxn];
bool cmp1(node aa, node bb)
{
    if (aa.l != bb.l) {
        return aa.l < bb.l;
    } else {
        return aa.l < bb.l;
    }
}
bool cmp2(node aa, node bb)
{
    return aa.id < bb.id;
}
int a[maxn];
int mx = -1;
int Next[maxn];
int pos[maxn];
int main()
{
    //freopen("D:\\code\\text\\input.txt","r",stdin);
    //freopen("D:\\code\\text\\output.txt","w",stdout);
    gbtb;
    cin >> n;
    repd(i, 1, n) {
        cin >> a[i];
    }
    for (int i = n; i >= 1; i--) {
        Next[i] = pos[a[i]];
        pos[a[i]] = i;
        mx = max(mx, a[i]);
    }
    for (int i = 0; i <= mx; ++i) {
        if (pos[i]) {
            add(pos[i], 1);
        }
    }
    cin >> m;
    repd(i, 1, m) {
        cin >> b[i].l >> b[i].r;
        b[i].id = i;
    }
    sort(b + 1, b + 1 + m, cmp1);
    int l = 1;
    repd(i, 1, m) {
        while (l < b[i].l) {
            if (Next[l]) {
                add(Next[l], 1);
                // add(l, -1);可有可无。
            }
            l++;
        }
        b[i].ans = ask(b[i].r) - ask(b[i].l - 1);
    }
    sort(b + 1, b + 1 + m, cmp2);
    repd(i, 1, m) {
        printf("%d\n", b[i].ans );
    }
    return 0;

}

inline void getInt(int *p)
{
    char ch;
    do {
        ch = getchar();
    } while (ch == ' ' || ch == '\n');
    if (ch == '-') {
        *p = -(getchar() - '0');
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 - ch + '0';
        }
    } else {
        *p = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 + ch - '0';
        }
    }
}


Guess you like

Origin www.cnblogs.com/qieqiemin/p/11516846.html