码迷,mamicode.com
首页 > 其他好文 > 详细

luoguP1972 [SDOI2009]HH的项链

时间:2018-08-05 14:24:19      阅读:122      评论:0      收藏:0      [点我收藏+]

标签:book   +=   oid   namespace   删除   顺序   add   bool   mes   

树状数组+排序。这种没有修改一眼就想到了离线。看了题解觉得挺神的。

但我想了想好像加个修改操作也可以,因为也可以按照修改操作顺序排序,

修改操作树状数组中只用 复原原来删的前面的数,删除修改的数。

#include<bits/stdc++.h>
using namespace std;
const int maxn=500010;
int n,m,c[maxn],a[maxn],re[maxn];
int book[1000010];
struct node{
    int x,y,num,ans;
}q[maxn];
int lowbit(int x){
    return x&-x;
}
void add(int x,int k){
    for(int i=x;i<=n;i+=lowbit(i)){
        c[i]+=k;
    }
}
int query(int x){
    int ret=0;
    for(int i=x;i>0;i-=lowbit(i)){
        ret+=c[i];
    }
    return ret;
}
bool cmp(const node&a,const node&b){
    return a.y<b.y;
}
bool cmp2(const node&a,const node&b){
    return a.num<b.num;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
        a[i]++;
        if(!book[a[i]]){
            re[i]=-1;
        }
        else{
            re[i]=book[a[i]];
        }
        book[a[i]]=i;
    }
    scanf("%d",&m);
    for(int i=1;i<=m;++i){
        int x,y;
        scanf("%d%d",&x,&y);
        q[i].x=x;q[i].y=y;q[i].num=i;
    }
    sort(q+1,q+1+m,cmp);
    int j=1;
    for(int i=1;i<=n;++i){
        if(re[i]==-1){
            add(i,1);
        }
        else{
            add(re[i],-1);
            add(i,1);
        }
        for(;j<=m;++j){
            if(q[j].y==i){
                q[j].ans=query(i)-query(q[j].x-1);
            }
            else{
                break;
            }
        }
    }
    sort(q+1,q+1+m,cmp2);
    for(int i=1;i<=m;++i){
        printf("%d\n",q[i].ans);
    }
    return 0;
}

 

luoguP1972 [SDOI2009]HH的项链

标签:book   +=   oid   namespace   删除   顺序   add   bool   mes   

原文地址:https://www.cnblogs.com/Dream-Runner/p/9425113.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!