• BZOJ 4939 [Ynoi2016]掉进兔子洞(莫队+bitset)


    【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=4939

    【题目大意】

      给出一个数列,每个询问给出三个区间,问除去三个区间共有的数字外,
      还剩下几个数字,注意删去的是共有的数字个数,不是数字种类,统计时候也一样

    【题解】

      首先,答案为区间长度和减去区间并数字个数和的三倍。
      所以题目转化为求区间并。很显然在开始对数据可以进行离散化。
      考虑每个数字只出现一次的情况,我们可以用bitset来统计区间某个数字是否存在,
      莫队处理查询每个区间,保存其bitset的值,最后求交即可,
      现在考虑每个数字出现多次的情况,
      我们发现经过离散的数据之间空位数量恰好可以用来标出现多次的数据,
      比如1 4 4 9 9,离散后为 1 2 2 4 4,
      我们可以将多出来的2标在3位置,4标在5位置,那么就可以用bitset统计了。
      - Me : 询问区间存不下怎么办?
      - Claris :将询问分批进行处理,单次处理25000个询问
      - Me : 超时了欸……
      - Claris : 这题卡常数,要手写bitset.
      - Me : 你的代码为什么有6.7k?
      - Claris :我分出现一次,两次和跟多次讨论
      - Me : 我……还是咸鱼吧……

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <bitset>
    #include <cmath>
    using namespace std;
    typedef unsigned long long ULL;
    const int N=100010,M=N<<2;
    int limit,n,m,pos[N],a[N],cnt[N],Ans[N],mark[N];
    struct Q{
        int l,r,id;
        friend bool operator < (const Q &a,const Q &b){
            return pos[a.l]<pos[b.l]||(pos[a.l]==pos[b.l]&&a.r<b.r);
        }
    }ask[M];
    int read(int &x){
        int f=1;char ch=getchar();x=0;
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        x*=f;
    }
    int disc[N];
    int remark(int x){
        int l=1,r=n,res=0;
        while(l<=r){
            int mid=(l+r)>>1;
            if(disc[mid]<x)l=mid+1;
            else res=mid,r=mid-1;
        }return res;
    }
    const int B=1567,K=25000;
    ULL v[B],f[K+3][B];
    int u[65537],tmp,U;
    void flip(int x){v[x>>6]^=1ULL<<(x&63);}
    void Copy(ULL*a){
        int i=0;
        for(;i+13<=U;i+=14){
            for(int j=0;j<14;j++)a[i+j]=v[i+j];
        }for(;i<=U;i++)a[i]=v[i];
    }
    void And(ULL*a){
        int i=0;
        for(;i+13<=U;i+=14){
            for(int j=0;j<14;j++)a[i+j]&=v[i+j];
        }for(;i<=U;i++)a[i]&=v[i];
    }
    void popcount(ULL x){tmp+=u[x&65535]+u[x>>16&65535]+u[x>>32&65535]+u[x>>48];}
    int count(ULL*a){
        int i=tmp=0;
        for(;i+13<=U;i+=14){
            for(int j=0;j<14;j++)popcount(a[i+j]);
        }for(;i<=U;i++)popcount(a[i]);
        return tmp;
    }
    void init(){for(int i=1;i<65536;i++)u[i]=u[i>>1]+(i&1);} 
    int main(){
        read(n); read(m);
        U=n>>6; init();
        limit=(int)sqrt(n+0.5);
        for(int i=1;i<=n;i++)read(a[i]),disc[i]=a[i],pos[i]=(i-1)/limit+1;
        sort(disc+1,disc+n+1);
        for(int i=1;i<=n;i++)a[i]=remark(a[i]);
        //for(int i=1;i<=n;i++)printf("%d
    ",a[i]); 
        int pos=0,l=1,r=0;
        while(pos<m){
            int tot=0;
            for(int i=1;i<=25000&&i+pos<=m;i++){
                tot+=3;
                Ans[i]=0;
                mark[i]=0;
                read(ask[i*3-2].l); read(ask[i*3-2].r); ask[i*3-2].id=i;
                read(ask[i*3-1].l); read(ask[i*3-1].r); ask[i*3-1].id=i;
                read(ask[i*3].l); read(ask[i*3].r); ask[i*3].id=i;
                Ans[i]+=ask[i*3-2].r-ask[i*3-2].l+1;
                Ans[i]+=ask[i*3-1].r-ask[i*3-1].l+1;
                Ans[i]+=ask[i*3].r-ask[i*3].l+1;
            }sort(ask+1,ask+tot+1);
            for(int i=1;i<=tot;i++){
                for(;r<ask[i].r;r++){flip(a[r+1]+cnt[a[r+1]]);cnt[a[r+1]]++;}
                for(;l>ask[i].l;l--){flip(a[l-1]+cnt[a[l-1]]);cnt[a[l-1]]++;}
                for(;l<ask[i].l;l++){cnt[a[l]]--;flip(a[l]+cnt[a[l]]);}
                for(;r>ask[i].r;r--){cnt[a[r]]--;flip(a[r]+cnt[a[r]]);}
                if(mark[ask[i].id])And(f[ask[i].id]);
                else Copy(f[ask[i].id]),mark[ask[i].id]=1;
            }tot/=3;
            for(int i=1;i<=tot;i++)printf("%d
    ",Ans[i]-3*count(f[i])); 
            pos+=tot;
        }return 0;
    }
  • 相关阅读:
    转自 Because of you 的总结
    转自 Good morning 的几句精辟的话
    (转)一句话小结各种网络流)
    上下界网络流总结
    浮云洲之战
    Poj3680 Intervals
    NOI2008假面舞会
    NOI2010航空管制
    python爬虫之反爬虫(随机user-agent,获取代理ip,检测代理ip可用性)
    python爬虫之反爬虫(随机user-agent,获取代理ip,检测代理ip可用性)
  • 原文地址:https://www.cnblogs.com/forever97/p/bzoj4939.html
Copyright © 2020-2023  润新知