zoukankan      html  css  js  c++  java
  • [BZOJ 2743] 采花

    Link:https://www.lydsy.com/JudgeOnline/problem.php?id=2743

    Algorithm:

    此题询问区间内出现次数超过1个的数字

    明显在线做无从下手,无法在区间两端无序的情况下统计符合要求的数字

    但可以发现,如果左端递增,是可以用树状数组维护右端数据的

    于是我们采取离线方式,将询问排序,左端点不断右移,树状数组随之更新即可

    先预处理出next和first数组

    每次走过一个数对nxt[i]--,nxt[nxt[i]]++

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef pair<int,int> P;
    typedef pair<P,int> PP;
    #define F first
    #define S second
    
    const int MAXN=1000010;
    int dat[MAXN],bit[MAXN],res[MAXN],nxt[MAXN],cur[MAXN],fst[MAXN],n,c,m;
    PP op[MAXN];
    
    inline int read()
    {
        char ch;int num,f=0;
        while(!isdigit(ch=getchar())) f|=(ch=='-');
        num=ch-'0';
        while(isdigit(ch=getchar())) num=num*10+ch-'0';
        return f?-num:num;
    }
    
    inline void write(long long x)
    {
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
    
    void update(int pos,int x)
    {
        while(pos<=n)
        {
            bit[pos]+=x;
            pos+=pos&(-pos);
        }
    }
    
    int cal(int pos)
    {
        int ret=0;
        while(pos)
        {
            ret+=bit[pos];
            pos-=pos&(-pos);
        }
        return ret;
    }
    
    int main()
    {
        n=read();c=read();m=read();
        fill(nxt,nxt+MAXN,MAXN-2);
        for(int i=1;i<=n;i++) dat[i]=read();
        for(int i=1;i<=m;i++) op[i].F.F=read(),op[i].F.S=read(),op[i].S=i;
        for(int i=1;i<=n;i++)  //预处理
        {
            if(!cur[dat[i]]) fst[dat[i]]=i;
            nxt[cur[dat[i]]]=i,cur[dat[i]]=i;
        }
        for(int i=1;i<=c;i++) if(nxt[fst[i]]) update(nxt[fst[i]],1);
        
        nxt[0]=0;op[0].F.F=1;
        sort(op+1,op+m+1);
        
        for(int i=1;i<=m;i++)  //离线
        {
            for(int j=op[i-1].F.F;j<op[i].F.F;j++)  //更新右端点
                update(nxt[nxt[j]],1),update(nxt[j],-1);
            res[op[i].S]=cal(op[i].F.S)-cal(op[i].F.F-1);
        }
        
        for(int i=1;i<=m;i++) write(res[i]),putchar('
    ');
        return 0;
    }

    Review:

    1、当数据维护与左端点的单调性有关时

          考虑排序后离线解题

    2、一般涉及询问出现字符个数的问题

         要预处理出nxt数组,滑动窗口来解题

  • 相关阅读:
    Code Review 五问五答
    JavaScript 10分钟入门
    swagger editor使用
    Tyk API网关介绍及安装说明
    Castle 多继承选择
    线程信息的获取和设置
    s3 api接口的调用
    在Hadoop集群上的HBase配置
    OpenStack 单元测试
    在Hadoop集群上的Hive配置
  • 原文地址:https://www.cnblogs.com/newera/p/9059938.html
Copyright © 2011-2022 走看看