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

    P1972 [SDOI2009]HH的项链

     

    说到sd的HH大哥,就十分有趣了。。。

    具体思路如下

    关于同一个数,我们记录它不超过当前区间的最后一次出现的位置。

    举例,假设一个区间为[l,5],数字分别为1,2,3,1,4,那么无论l取几,只要包含了第4个数"1","1"这个数也就出现过了,不必管之前的"1"在哪里

    那么我们记录一个数最后出现的位置,将区间按右端点从小到大排序

    若每次只更新到当前区间的右端点

    if(更新到的数出现过)则将上一次出现的位置的tree--;当前位置的tree++,更新完就区间查询存储答案,最后将查询恢复排序输出答案

    代码如下:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cctype>
    #define ll long long
    #define gc() getchar()
    #define maxn 5000005
    using namespace std;
    inline ll read(){
        ll a=0;int f=0;char p=gc();
        while(!isdigit(p))
        {
            f|=p=='-';
            p=gc();
        }
        while(isdigit(p))
        {
            a=(a<<3)+(a<<1)+(p^48);
            p=gc();
        }
        return f?-a:a;
    }
    void write(ll a){
        if(a>9)
            write(a/10);
        putchar(a%10+'0');
    }
    int n,m,a[maxn],b[10000005];
    struct ahaha{
        int l,r,ans,zz;
    }q[maxn>>1];
    inline bool cmp1(ahaha x,ahaha y){
        return x.r<y.r;
    }
    inline bool cmp2(ahaha x,ahaha y){
        return x.zz<y.zz;
    }
    #define lowbit(i) i&-i
    int tree[maxn];
    inline void update(int x,int z){
        while(x<=n){
            tree[x]+=z;
            x+=lowbit(x);
        }
    }
    inline int query(int x){
        int ans=0;
        while(x){
            ans+=tree[x];
            x-=lowbit(x);
        }
        return ans;
    }
    int main(){
        n=read();
        for(int i=1;i<=n;++i)
            a[i]=read();
        m=read();
        for(int i=1;i<=m;++i)
            q[i].l=read(),q[i].r=read(),q[i].zz=i;
        sort(q+1,q+m+1,cmp1);
        for(int i=1;i<=m;++i){
            for(int j=q[i-1].r+1;j<=q[i].r;++j){
                if(b[a[j]])
                    update(b[a[j]],-1);
                b[a[j]]=j;update(b[a[j]],1);
            }
            q[i].ans=query(q[i].r)-query(q[i].l-1);
        }
        sort(q+1,q+m+1,cmp2);
        for(int i=1;i<=m;++i)
            write(q[i].ans),putchar('
    ');
        return 0;
    }
  • 相关阅读:
    instruments 内存泄漏
    ios常用数学函数
    正则表达式
    view设置成圆角
    关于新浪微博注销后自动登录的问题
    根据视频地址获取某一帧的图像
    使用DES加解密
    实现通讯录的查询与删除
    iOS 动画效果
    iOS 文字下划线
  • 原文地址:https://www.cnblogs.com/gongcheng456/p/12912737.html
Copyright © 2011-2022 走看看