zoukankan      html  css  js  c++  java
  • [BZOJ1878][SDOI2009] HH的项链 (树状数组)

    link

    一道简单题。

    不用可持久化。

    对于统计颜色个数,可以看与其颜色一样的前一个位置。

    设$las(i)$表示其与$i$颜色相等的上一个位置。

    则对于二元组$(l,r)$,其答案为$sum_{i=l}^{r} las(i)<=l-1$。

    可持久化强上即可。

    若不用的话可以讲$(l,r)$拆成两个操作,然后对于其排序即可,每次维护从$[1,x]$中小于等于$l-1$的和,然后就每次动态加点,查询,省略了其可持久化的过程。

    所以做两次树状数组,但是因为树状数组不能有$0$所以需要$+1$。

    离散化方便寻找$las(i)$,不需要链表什么的。

    时间复杂度:$O(nlog n)$

    正确性显然。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'|c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int MAXN=500001;
    
    int n,a[MAXN],m,tot,tmp[MAXN],M[MAXN],las[MAXN],Ans[MAXN];
    struct BIT{
        int c[MAXN];
        inline int lowbit(int x){return x&-x;} 
        inline void add(int x){
            for(;x<=n;x+=lowbit(x)) c[x]++;
            return;
        }
        inline int qsum(int x){
            int res=0;
            for(;x;x-=lowbit(x)) res+=c[x];
            return res; 
        }
        inline void clear(){memset(c,0,sizeof(c));return;}
    }bit;
    struct Query{
        int pos,opt,k,id;
    }query[MAXN<<1];
    bool cmp(Query x1,Query x2){
        if(x1.opt==x2.opt) return x1.pos<x2.pos;
        return x1.opt<x2.opt;
    }
    int main(){
    //    freopen("5.in","r",stdin);
        n=read();
        for(int i=1;i<=n;i++) a[i]=tmp[++tmp[0]]=read();
        sort(tmp+1,tmp+n+1);
        for(int i=1;i<=n;i++) a[i]=lower_bound(tmp+1,tmp+n+1,a[i])-tmp;
        for(int i=1;i<=n;i++) las[i]=M[a[i]]+1,M[a[i]]=i;
        m=read();
        for(int i=1;i<=m;i++){
            int l=read(),r=read();
            query[++tot].pos=l-1,query[tot].opt=-1,query[tot].k=l,query[tot].id=i;
            query[++tot].pos=r,query[tot].opt=1;query[tot].k=l,query[tot].id=i;
        }
        sort(query+1,query+tot+1,cmp);
        int l=1,r=m+1;bit.clear();
        while(query[l].pos==0&&l<=m) l++;
        while(query[r].pos==0&&r<=2*m) r++;
        for(int i=1;i<=n;++i){
            bit.add(las[i]);
            while(l<=m&&query[l].pos==i) Ans[query[l].id]-=bit.qsum(query[l].k),++l;
            while(r<=2*m&&query[r].pos==i) Ans[query[r].id]+=bit.qsum(query[r].k),++r;
        }
        for(int i=1;i<=m;i++) printf("%d
    ",Ans[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    连接MySQL错误:Can't connect to MySQL server (10060)
    PHP性状的使用
    PHP interface(接口)的示例代码
    jquery 设置页面元素不可点击、不可编辑、只读(备忘)
    ace_admin_1.3.1 wysiwyg 工具条下拉出不来
    类函数和对象函数 PHP
    PHP 回调、匿名函数和闭包
    simplexml_load_file 抑制警告的直接输出
    jQuery判断当前元素是第几个元素
    hihocoder #1445 : 后缀自动机二·重复旋律5
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/10423791.html
Copyright © 2011-2022 走看看