• HH的项链(树状数组+离线处理)


    1878: [SDOI2009]HH的项链


    题目描述

    HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此, 他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同 的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只好求助睿智的你,来解 决这个问题。

    输入

    第一行:一个整数N,表示项链的长度。 第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。 第三行:一个整数M,表示HH询问的个数。 接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。

    输出

    M行,每行一个整数,依次表示询问对应的答案。

    样例输入

    6
    1 2 3 4 3 5
    3
    1 2
    3 5
    2 6

    样例输出

    2
    2
    4

    提示


    对于20%的数据,N ≤ 100,M ≤ 1000;
    对于40%的数据,N ≤ 3000,M ≤ 200000;
    对于100%的数据,N ≤ 50000,M ≤ 200000。

    解析

    这是一个树状数组+离线处理的T;

    先将询问按L排序,再一维循环边将每个询问L之前有重复的数在下一个位置的统计个数+1(next[]和树状数组自己预处理写吧)

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,m,a[50002],tr[50002],x;
    int maxi=0,fs[1000002]={0},next[50002]={0};
    struct node{
        int x,y,id,ans;
    }q[200002];
    int max(int a,int b){return a>b?a:b;}
    bool rule1(node a,node b){
        return a.x==a.y?a.y<b.y:a.x<b.x;
    }
    bool rule2(node a,node b){
        return a.id<b.id;
    }
    int lowbit(int x){
        return x&(-x);
    }
    void updata(int x,int v){     //求树状数组
        for(int i=x;i<=n;i+=lowbit(i)){
            tr[i]+=v;
        }
    }
    int visit(int x){             //求a[1]~a[x]的和 
        int tmp=0;
        for(int i=x;i>0;i-=lowbit(i)){
            tmp+=tr[i];
        }
        return tmp;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {
            scanf("%d",a+i);
            maxi=max(maxi,a[i]);
        }
        for(int i=n;i>=1;i--) next[i]=fs[a[i]],fs[a[i]]=i;
        for(int i=1;i<=maxi;i++) 
            if(fs[i]) updata(fs[i],1);
        scanf("%d",&m);
        for(int i=1;i<=m;i++) scanf("%d%d",&q[i].x,&q[i].y),q[i].id=i;
        sort(q+1,q+m+1,rule1);      //按q[i].x排序 
        x=1;
        for(int i=1;i<=m;i++){
            while(x<q[i].x){                 //将q[i].x之前有重复值的数的下一次出现位置所统计的个数tr[next[x]]++
                if(next[x]) updata(next[x],1);
                x++;
            }
            q[i].ans=visit(q[i].y)-visit(q[i].x-1);
        }    
        sort(q+1,q+m+1,rule2);      //按q[i].id排序 
        for(int i=1;i<=m;i++) printf("%d
    ",q[i].ans);
        return 0;
    }
    View Code
  • 相关阅读:
    python 5 条件判断
    python 4学习 list 和 tuple
    python 3 学习字符串和编码
    python 1 学习廖雪峰博客
    c++11 thread的学习
    C++ 11 Lambda表达式!!!!!!!!!!!
    c++11 右值的学习
    TreeMap
    二分查找
    solr in action 第三章
  • 原文地址:https://www.cnblogs.com/qingang/p/5713395.html
Copyright © 2020-2023  润新知