Luo Gu [SP3267] DQUERY - D-query

DQUERY - D-query

Title Description

Given a sequence of \(n\) numbers \(a_{1},a_{2},...,a_{n}\) and a number of d-queries. A d-query is a pair \((i,j)\) \((1 \le i \le j \le n)\). For each d-query \((i,j)\), you have to return the number of distinct elements in the subsequence \(a_{i},a _{i+1},...,a_{j}\).

Input Format

  • Line 1: \ (n \) \ ((1 \ n 30000) \) .
  • Line 2: n numbers \(a_{1},a_{2},...,a_{n}\) \((1 \le a_{i} \le 10^{6})\).
  • Line 3: \(q\) \((1 \le q \le 200000)\), the number of d-queries.
  • In the next \(q\) lines, each line contains \(2\) numbers \(i\),\(j\) representing a d-query \((1 \le i \le j \le n)\).

Output Format

  • For each d-query \((i,j)\), print the number of distinct elements in the subsequence \(a_{i},a_{i+1},...,a_{j}\) in a single line.

Translation of the meaning of problems

A given length of \ (n-\) is the number of columns, \ (A_ {}. 1, A_ {2}, ..., n-A_ {} \) , there are \ (Q \) a query, query given every number of \ ((I, J) \) \ ((I, J) \) , you need to give \ (a_ {i}, a_ {i + 1}, ..., a_ {j} \) which how many different numbers in a while there is

Sample input

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

Sample Output

3
2
3

answer

Meaning of the title: Translation it. . .
This is a team board Mo title. (Obvious)
fact, I was just learning team Mo, Mo for the team may also have some misconceptions, if there is an incorrect interpretation please big brother said.
It is said that the need to do as a team title Mo, Mo began to learn so the team.
Originally I thought Mo team is very difficult, after reading other people's blog feel do not understand (the elegant violence?), And then began to look at the code written by someone else and board title.
then. . .
It really is elegant TM violence! ! !
Well, Tucao finished, in fact, as long as you know Mo team is in fact the essence of violence, but in a special way it came in a sequence.
We consider a violent, with \ (CNT [] \) and \ (l, r \) Maintenance \ (L \) to \ (R & lt \) the number of digits of each interval (because the maximum size of a digital \ (10 ^ 6 \) ), and maintains a \ (ans \) value, and then we move \ (l \) and \ (r \) when you can quickly and maintain the array \ (ans \) worth it.
But we can find the time complexity of words such direct maintenance or \ (O (n ^ 2) \) is.
So we consider off-line operation, row a sequence of inquiry input.
If we follow the inquiry \ (l \)Values in ascending order, the maintenance interval \ (l \) will move to the right, it may be a little less time, but think what you will find this method is likely to be card into \ (O (n ^ 2 ) \) , for example in accordance with the inquiry \ (L \) sorted \ (R & lt \) value is large and small, then the query time complexity of each are \ (O (n-) \) .
Then we began to talk about the team Mo, Mo team is to use the idea of the block, we ask in \ (\ frac {l} { \ sqrt {n}} \) the same number of grouped size (chunked here is \ (\ sqrt {n} \ ) , then generally random data area \ (\ sqrt {n} \ ) would be better, but different block sizes subject may be different)
and then ask the same group , we follow the inquiry \ (r \) values in ascending order.
Thus you will find in each \ (\ sqrt {n} \ ) within the interrogation times, because each interval \ (R & lt \) values in ascending order, so you move distance interval most \ (n + \ sqrt n-*} {\ n-sqrt {} \) (approximately \ (n-\) ), then the time complexity of Mo is team \ (O (n-\ n-sqrt {}) \) .
On the code:

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[30009];
struct aa{
    int l,r,x,ans;
}p[200009];
int sq;
bool cmp(aa x,aa y){//按照莫队算法排序
    if(x.l/sq<y.l/sq) return 1;
    if(x.l/sq>y.l/sq) return 0;
    return x.r<y.r;
}
int cnt[1000009];
bool cmpp(aa x,aa y){return x.x<y.x;}
int main(){
    scanf("%d",&n);
    sq=sqrt(n);
    for(int j=1;j<=n;j++)
        scanf("%d",&a[j]);
    scanf("%d",&m);
    for(int j=1;j<=m;j++){
        scanf("%d%d",&p[j].l,&p[j].r);
        p[j].x=j;//因为最后输出要按输入的顺序输出,所以这里记录输入的顺序
    }
    sort(p+1,p+m+1,cmp);
    int ll=1,rr=1,ss=1;
    cnt[a[1]]=1;
    for(int j=1;j<=m;j++){
        while(rr<p[j].r){
            rr++;
            cnt[a[rr]]++;
            if(cnt[a[rr]]==1) ss++;
        }
        while(ll>p[j].l){
            ll--;
            cnt[a[ll]]++;
            if(cnt[a[ll]]==1) ss++;
        }
        while(rr>p[j].r){
            cnt[a[rr]]--;
            if(cnt[a[rr]]==0) ss--;
            rr--;
        }
        while(ll<p[j].l){
            cnt[a[ll]]--;
            if(cnt[a[ll]]==0) ss--;
            ll++;
        }
        p[j].ans=ss;//记录答案
    }
    sort(p+1,p+m+1,cmpp);
    for(int j=1;j<=m;j++)
        printf("%d\n",p[j].ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/linjiale/p/11761445.html