BZOJ 2743

来源:互联网 发布:odf格式 知乎 编辑:程序博客网 时间:2024/06/05 04:31

【题目分析】
树状数组+离线


【代码】

#include <cstdio>#include <cmath>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int next[1000001];int last[1000001];int first[1000001];int a[1000001];int t[1000001];int l[1000001];int r[1000001];int rank[1000001];int ans[1000001];int n,c,m;inline void add(int k,int f){//  cout<<"add in "<<k<<" "<<f<<endl;    for (;k<=n;k+=k&(-k)) t[k]+=f;}inline int gs(int k){    int ret=0;    for (;k;k-=k&(-k)) ret+=t[k];    return ret;}inline bool cmp(int a,int b){return l[a]<l[b];}int main(){    scanf("%d%d%d",&n,&c,&m);    for (int i=1;i<=n;++i) scanf("%d",&a[i]);    for (int i=n;i;--i)    {//      scanf("%d",&a[i]);//      if (!last[a[i]]) first[a[i]]=i;        next[i]=last[a[i]];        last[a[i]]=i;    }//  for (int i=1;i<=n;++i) printf("%d ",next[i]);printf("\n");    for (int i=1;i<=c;++i)        if (next[last[i]]) add(next[last[i]],1);    for (int i=1;i<=m;++i)    {        scanf("%d%d",&l[i],&r[i]);        rank[i]=i;    }    sort(rank+1,rank+m+1,cmp);     int ll=1;    for (int i=1;i<=m;++i)    {        int nl=l[rank[i]],nr=r[rank[i]];//      cout<<nl<<" "<<nr<<endl;        while (ll<nl)        {            if (next[ll]) add(next[ll],-1);            if (next[next[ll]]) add(next[next[ll]],1);            ll++;        }//      cout<<"ans "<<gs(nr)-gs(nl-1)<<endl;        ans[rank[i]]=gs(nr)-gs(nl-1);    }    for (int i=1;i<=m;++i) printf("%d\n",ans[i]);}
0 0
原创粉丝点击