HH的项链

加强数据狂魔chen_zhe加强了数据

洛谷的数据啊, 不加快读没过去

题目描述

HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此,他的项链变得越来越长。

有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答…… 因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。

输入格式

一行一个正整数 n,表示项链长度。

第二行 n 个正整数 \(a_i\) ,表示项链中第 ii 个贝壳的种类。

第三行一个整数 m,表示 H 询问的个数。

接下来 m 行,每行两个整数 l,r,表示询问的区间。

输出格式

输出 m 行,每行一个整数,依次表示询问对应的答案。

输入输出样例

输入

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

输出

2
2
4

说明/提示
【数据范围】

对于 20% 的数据,1≤n,m≤5000;
对于 40% 的数据,1≤n,m≤$10^5$;
对于 60% 的数据,1≤n,m≤$5×10^5$ ;
对于 100% 的数据,1≤n,m,$a_i$ ≤$10^6$
本题可能需要较快的读入方式,最大数据点读入数据约 20MB

题解

链式前向星存储位置

对于每个询问[l,r],只有next[i]<l(l<=i<=r)的贝壳才会被算进答案

可以用离线算法,用一个数组vecl[i], recr[i]来记录位置和对应的询问的关系

对于每个询问,只需要用树状数组查询有多少个next[i]满足0<=pre[i]<=l-1(l<=i<=r)即可

具体见代码

代码

#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define RE register
#define rep(i,a,b) for(RE int i=a;i<=(b);++i)
#define per(i,a,b) for(RE int i=a;i>=(b);--i)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;

const int N = 1e6 + 5;

int n, m, _, k;
int c[N], ans[N];
int h[N], ne[N];
VI vecl[N]; 
vector<PII> vecr[N];

inline int read()
{
	int x = 0, f = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-')  f = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9')
	{
		x = x * 10 + c - '0';
		c = getchar();
	}
	return f * x;
}

inline void add(RE int x, RE int k) {
	if (x == 0) { c[0] += k; return; }

  	for (;x <= n; x += x & -x) c[x] += k;
}

inline int ask(RE int x) {
  	RE int ans = c[0];
  	for (; x; x -= x & -x) ans += c[x];
  	return ans;
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
    n = read();
    rep (i, 1, n) {
        m = read(); 
        ne[i] = h[m]; h[m] = i;
    }

    cin >> m;
    rep (i, 1, m) {
        int l, r; l = read(), r = read();
        vecl[l].pb(i);
        vecr[r].pb({ i, l - 1 });
    }

    rep (i, 1, n) {
        add(ne[i], 1);

		int s = ask(i);
		for (int j : vecl[i + 1]) ans[j] -= s;
		for (PII j : vecr[i]) ans[j.fi] += ask(j.se);
    }

    rep (i, 1, m) cout << ans[i] << '\n';

    return 0;
}
posted @ 2020-06-28 18:41  洛绫璃  阅读(134)  评论(0编辑  收藏  举报