zoukankan      html  css  js  c++  java
  • BZOJ4939 Ynoi2016掉进兔子洞(莫队+bitset)

      容易发现要求三个区间各数出现次数的最小值。考虑bitset,不去重离散化后and一发就可以了。于是莫队求出每个区间的bitset。注意空间开不下,做多次即可。输出的东西错了都能调一年服了我了。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<bitset>
    using namespace std;
    #define ll long long
    #define N 100050
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int n,m,a[N],b[N],cnt[N],ans[N],block;
    bitset<N> f[N>>2],tot;
    struct data{int l1,r1,l2,r2,l3,r3;
    }c[N];
    struct data2
    {
        int l,r,i,k;
        bool operator <(const data2&a) const
        {
            return k<a.k||k==a.k&&(k&1?r>a.r:r<a.r);
        }
    }q[N];
    void solve(int L,int R)
    {
        if (L>R) return;
        int m=R-L+1;
        for (int i=1;i<=m;i++)
        {
            q[i*3-2].i=i,q[i*3-2].l=c[i+L-1].l1,q[i*3-2].r=c[i+L-1].r1,q[i*3-2].k=q[i*3-2].l/block;
            q[i*3-1].i=i,q[i*3-1].l=c[i+L-1].l2,q[i*3-1].r=c[i+L-1].r2,q[i*3-1].k=q[i*3-1].l/block;
            q[i*3].i=i,q[i*3].l=c[i+L-1].l3,q[i*3].r=c[i+L-1].r3,q[i*3].k=q[i*3].l/block;
        }
        sort(q+1,q+m*3+1);
        for (int i=1;i<=m;i++) f[i].set();tot=0;
        memset(ans,0,sizeof(ans));
        memset(cnt,0,sizeof(cnt));
        int l=1,r=0;
        for (int i=1;i<=m*3;i++)
        {
            ans[q[i].i]+=q[i].r-q[i].l+1;
            while (r<q[i].r) r++,tot[a[r]+(cnt[a[r]]++)]=1;
            while (l>q[i].l) l--,tot[a[l]+(cnt[a[l]]++)]=1;
            while (r>q[i].r) tot[a[r]+(--cnt[a[r]])]=0,r--;
            while (l<q[i].l) tot[a[l]+(--cnt[a[l]])]=0,l++;
            f[q[i].i]&=tot;
        }
        for (int i=1;i<=m;i++)
        printf("%d
    ",ans[i]-3*f[i].count());
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj4939.in","r",stdin);
        freopen("bzoj4939.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read();block=sqrt(n);
        for (int i=1;i<=n;i++) b[i]=a[i]=read();
        sort(b+1,b+n+1);
        for (int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+n+1,a[i])-b-1;
        for (int i=1;i<=m;i++) c[i].l1=read(),c[i].r1=read(),c[i].l2=read(),c[i].r2=read(),c[i].l3=read(),c[i].r3=read();
        solve(1,m/4),solve(m/4+1,m/2),solve(m/2+1,m-m/4),solve(m-m/4+1,m);
        return 0;
    }
  • 相关阅读:
    词法分析程序
    大数据概述作业
    编译原理心得
    简化C语言文法
    解决:eclipse引入一个新项目所有jsp报错
    解决: 启动tomcat java.net.BindException: Address already in use: JVM_Bind错误
    myeclipse优化
    jquery冲突
    QQ上传大文件为什么这么快
    java中的重写和重载
  • 原文地址:https://www.cnblogs.com/Gloid/p/10051400.html
Copyright © 2011-2022 走看看