zoukankan      html  css  js  c++  java
  • [SDOI2009]HH的项链

    题目描述

    有一个序列,每次询问区间内有多少不同元素,元素值小于 \(1e6\)

    解法

    考虑到每个元素都只有在区间内和不在区间内两种状态,而没有修改操作,考虑离线询问。用 \(flag[a[j]]\) 表示 \(a[j]\) 这个元素的最后一次的出现位置。遇到一个新的元素,若 \(flag[a[j]]\) 有值,则把这个位置在树状数组里的值删去,并加上新的这个 \(a[j]\) 的位置。这样同种元素只会被记录一次,再用树状数组维护前缀和,最后做差就是答案。

    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    #define N 1000007
    struct Pos{
        int l,r;
        int pos;
    }node[N>>1];
    int tr[N],ans[N],flag[N];
    int a[N>>1],n,m;
    inline void read(int &x){
        x=0;char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
    }
    inline bool cmp(Pos x,Pos y){
        return x.r<y.r;
    }
    inline int lowbit(int x){return (-x)&x;}
    inline void update(int u,int val){
        while(u<=n){
            tr[u]+=val;
            u+=lowbit(u);
        }
    }
    inline int query(int u){
        int rest=0;
        while(u>0){
            rest+=tr[u];
            u-=lowbit(u);
        }
        return rest;
    }
    int main(){
        read(n);
        for(int i=1;i<=n;i++) read(a[i]);
        read(m);
        for(int i=1;i<=m;i++) read(node[i].l),read(node[i].r),node[i].pos=i;
        sort(node+1,node+1+m,cmp);
        int next=1;
        for(int i=1;i<=m;i++){
            for(int j=next;j<=node[i].r;j++){
                if(flag[a[j]]) update(flag[a[j]],-1);
                update(j,1);
                flag[a[j]]=j;
            }
            next=node[i].r+1;
            ans[node[i].pos]=query(node[i].r)-query(node[i].l-1);
        }
        for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
    } 
    
  • 相关阅读:
    团队开发——描绘用户场景
    学习EXTJS6(2)“Hello Usegear”
    D2007从win7升级到win10下的莫名其妙问题。
    学习EXTJS6(1)安装环境
    raize5的修改。
    EurekaLog是什么鬼?
    EditorLineEnds.ttr的困扰
    dev的汉化
    cxGrid主从表删除从表记录的困惑
    痛苦的Windows下的temp目录
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/13618834.html
Copyright © 2011-2022 走看看