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
  • 相关阅读:
    LeetCode Subsets II
    LeetCode Rotate Image
    LeetCode Palidrome Number
    LeetCode Generate Parentheses
    LeetCode Maximum Subarray
    LeetCode Set Matrix Zeroes
    LeetCode Remove Nth Node From End of List
    Linux Loop设备 使用
    Linux 文件系统大小调整
    LeetCode N-Queens II
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/10423791.html
Copyright © 2011-2022 走看看