【luogu1972】SDOI2009 HH的项链

学树状数组之后做的(除了板子)之后的第一道题吧

题目链接 https://www.luogu.com.cn/problem/P1972

大意就是区间查询

先对所有询问做一个排序

然后树状数组就维护前缀和

具体见代码(啊 我高三的码风真的丑 我现在都没眼看

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=500005;
const int maxa=1000005;
int judge[maxa];
int c[maxn];
int n,m;
int num[maxn];
struct ques
{
    int l,r,index,ans;
}a[maxn];
bool cmpr(ques a,ques b)
{
    return a.r<b.r;
}
bool cmpindex(ques a,ques b)
{
    return a.index<b.index;
}
int lowbit(int x) {return x&(-x);}
int getsum(int x)
{
    int ans=0;
    while(x>=1)
    {
        ans+=c[x];
        x-=lowbit(x);
    }
    return ans;
}
void insert(int k,int x)
{
    while(k<=n)
    {
        c[k]+=x;
        k+=lowbit(k);
    }
    return  ;
}
int main()
{
    scanf("%d",&n);
    for(register int i=1;i<=n;++i)
    {
        //cin>>num[i];
        scanf("%d",&num[i]);
    }
    cin>>m;
    for(register int i=1;i<=m;++i)
    {
        //cin>>a[i].l>>a[i].r;
        scanf("%d%d",&a[i].l,&a[i].r);
        a[i].index=i;
    }
    sort(a+1,a+1+m,cmpr);
    int k=1;
    for(register int i=1;i<=n;++i)
    {
        if(judge[num[i]]==0)
        {
            judge[num[i]]=i;
            insert(i,1);
        }
        else
        {
            insert(judge[num[i]],-1);
            insert(i,1);
            judge[num[i]]=i;
        }
        while(a[k].r==i)
        {
            a[k].ans=getsum(a[k].r)-getsum(a[k].l-1);
            ++k;
        }
    }
    sort(a+1,a+1+m,cmpindex);
    for(register int i=1;i<=m;++i)  printf("%d\n",a[i].ans);
    return 0;
}
        
posted @ 2019-12-11 16:28  Suzuko  阅读(100)  评论(0)    收藏  举报