#树状数组#洛谷 1972 JZOJ 1097 HH的项链

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sugar_free_mint/article/details/88364647

题目

问区间中数的种类


分析

那么由于这道题没有修改,所以可以用树状数组离线回答,对于左区间排序,然后用树状数组统计


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
struct rec{int l,r,rk;}b[500001];
int n,m,ans[500001],a[500001],c[500001],pos[1000001];
inline signed iut(){
    rr int ans=0; rr char c=getchar();
    while (!isdigit(c)) c=getchar();
    while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    return ans;
}
bool cmp(rec t1,rec t2){return t1.r<t2.r;}
inline void print(int ans){
    if (ans>9) print(ans/10);
    putchar(ans%10+48);
}
inline void add(int x,int y){
    while (x<=n){
        c[x]+=y;
        x+=-x&x;
    }
}
inline signed answ(int x){
    rr int ans=0;
    while (x){
        ans+=c[x];
        x-=-x&x;
    }
    return ans;
}
signed main(){
    n=iut(); for (rr int i=1;i<=n;++i) a[i]=iut();
    m=iut(); for (rr int i=1;i<=m;++i) b[i]=(rec){iut(),iut(),i};
    sort(b+1,b+1+m,cmp); rr int now=1;
    for (rr int i=1;i<=m;++i){
        for (rr int j=now;j<=b[i].r;++j){
            if (pos[a[j]]) add(pos[a[j]],-1);
            add(pos[a[j]]=j,1);
        }
        now=b[i].r+1;
        ans[b[i].rk]=answ(b[i].r)-answ(b[i].l-1);
    }
    for (rr int i=1;i<=m;++i) print(ans[i]),putchar(10);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sugar_free_mint/article/details/88364647
今日推荐