[P1972] HH Luo Gu necklace

topic

Topic links: https://www.luogu.com.cn/problem/P1972
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 shell out a while, thinking the meaning they express. HH constantly collecting new shell, so he's getting longer necklace.
One day, he suddenly raises the question: a certain period of shells, including how many different shells? This question is difficult to answer ...... because the necklace is too long. So he had to help you wise, to solve this problem.

Thinking

Before writing team is Mo \ (O (n \ sqrt { n}) \) algorithm. Now the data has strengthened, then come back to write a \ (O (n \ log n ) \) algorithm.
Consider for a bunch of \ (r_i = x \) asked \ (i \) , we found that if a number in the \ ([1, x] \ ) appeared several times, then take a maximum of not more than \ ( x \) digital position is clearly the best.
So we are dealing with the same right to ask a bunch of points, as long as we know in \ ([1, x] \ ) in the final position of each digit appears where you can.
Establishing a tree array, the process \ (x = i \) , the position in the array tree \ (J \) represents the interval \ ([1, i] \ ) , the position \ (\ J) on if the number is (it is the last occurrence of \ (C [I] \ in \ {0,1 \} \) ). Then the time for a query \ ([L, X] \) , the answer is \ (\ SUM _ ^ {X} L {I} = C [I] \) . Fenwick tree \ (O (\ log n) \) get.
From position \ (I \) transferred to the position inquiry\ (i + 1 \) at the time of inquiry, we \ (a [i + 1] \) position of the first occurrence in the tree on the array is cleared, the position \ (i + 1 \) labeled 1. Still \ (O (\ log n)
\) time complexity \ (O (n \ log n ) \)

Code

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;

const int N=1000010;
int n,m,a[N],last[N],ans[N];

struct ASK
{
    int l,r,id;
}ask[N];

struct BIT
{
    int c[N];
    
    int ask(int x)
    {
        int sum=0;
        for (int i=x;i;i-=i&-i)
            sum+=c[i];
        return sum;
    }
    
    void add(int x,int val)
    {
        if (!x) return;
        for (int i=x;i<=n;i+=i&-i)
            c[i]+=val;
    }
}bit;

bool cmp(ASK x,ASK y)
{
    return x.r<y.r;
}

int read()
{
    int d=0,f=1; char ch=getchar();
    while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar();
    while (isdigit(ch)) d=(d<<3)+(d<<1)+ch-48,ch=getchar();
    return d*f;
}

int main()
{
    n=read();
    for (int i=1;i<=n;i++)
        a[i]=read();
    m=read();
    for (int i=1;i<=m;i++)
        ask[i].l=read(),ask[i].r=read(),ask[i].id=i;
    sort(ask+1,ask+1+m,cmp);
    for (int i=1;i<=m;i++)
    {
        for (int j=ask[i-1].r+1;j<=ask[i].r;j++)
            bit.add(last[a[j]],-1),bit.add(j,1),last[a[j]]=j;
        ans[ask[i].id]=bit.ask(ask[i].r)-bit.ask(ask[i].l-1);
    }
    for (int i=1;i<=m;i++)
        printf("%d\n",ans[i]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/stoorz/p/12207743.html