zoukankan      html  css  js  c++  java
  • 离线二次莫队

    洛谷P4887 第十四分块(前体)

    考虑莫队计算答案,显然对区间询问可以转化成对前缀计算对某个值的贡献查询$O(n sqrt{n})$次。

    把莫队中的查询离线计算,从前往后推算,可以在$O(C(14,7))$中修改,$O(1)$查询。

    由于修改$O(n)$次,查询$O(n sqrt{n})$次,复杂度$O(n sqrt{n}+C(14,7)n)$。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb push_back
    const int N=100005,M=16384,W=350;
    int n,m,k,tp,stk[3433],a[N],c[N];ll p1[N],p2[N],res[N<<1],ans[N]; 
    struct st{int l,r,i;}q[N];vector<st>g[N]; 
    inline bool cmp(st a,st b){return a.l/W^b.l/W?a.l<b.l:a.r<b.r;}
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=m;i++){scanf("%d%d",&q[i].l,&q[i].r);q[i].i=i;}
        for(int i=0;i<M;i++)
        {
            int c=0;for(int j=0;j<14;j++)c+=i>>j&1;
            if(c==k)stk[++tp]=i;
        }
        sort(q+1,q+m+1,cmp);int l=1,r=0;
        for(int i=1;i<=m;i++)
        {
            if(l<q[i].l)g[r].pb((st){l,q[i].l-1,i<<1});else if(l>q[i].l)g[r].pb((st){q[i].l,l-1,i<<1});l=q[i].l;
            if(r<q[i].r)g[l-1].pb((st){r+1,q[i].r,i<<1|1});else if(r>q[i].r)g[l-1].pb((st){q[i].r+1,r,i<<1|1});r=q[i].r;
        }
        for(int i=1;i<=n;i++)
        {
            p1[i]=p1[i-1]+c[a[i]];
            for(int j=1;j<=tp;j++)c[a[i]^stk[j]]++;
            p2[i]=p2[i-1]+c[a[i]];
            for(int j=0;j<g[i].size();j++)
            {
                st t=g[i][j];
                for(int k=t.l;k<=t.r;k++)res[t.i]+=c[a[k]];
            } 
        }
        l=1,r=0;ll s=0;
        for(int i=1;i<=m;i++)
        {
            if(l<q[i].l)s+=p2[q[i].l-1]-p2[l-1]-res[i<<1];else if(l>q[i].l)s+=res[i<<1]+p2[q[i].l-1]-p2[l-1];l=q[i].l;
            if(r<q[i].r)s+=p1[q[i].r]-p1[r]-res[i<<1|1];else if(r>q[i].r)s+=res[i<<1|1]-p1[r]+p1[q[i].r];r=q[i].r;ans[q[i].i]=s;
        }
        for(int i=1;i<=m;i++)printf("%lld
    ",ans[i]);
        return 0;
    } 
    //        while(l<q[i].l){g[r].push_back((st){l,-1,i});g[l].push_back((st){l,1,i});l++;}
    //        while(l>q[i].l){l--;g[r].push_back((st){l,1,i});g[l].push_back((st){l,-1,i});}
    //        while(r<q[i].r){r++;g[r-1].push_back((st){r,1,i});g[l-1].push_back((st){r,-1,i});}
    //        while(r>q[i].r){g[r-1].push_back((st){r,-1,i});g[l-1].push_back((st){r,1,i});r--;}

    洛谷P5398 [Ynoi2018]GOSICK

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb push_back
    const int N=100005,M=100000,W=500;
    int n,m,a[N],b[N],c[N],ss[N],r1[N],r2[N],r3[N],r4[N];ll p1[N],p2[N],res[N<<1],ans[N]; 
    struct st{int l,r,i;}q[N];vector<st>g[N];vector<int>V[N];
    inline bool cmp(st a,st b){return a.l/W^b.l/W?a.l<b.l:a.r<b.r;}
    inline void init()
    {
        for(int i=1;i<=M;i++)for(int j=i;j<=M;j+=i)V[j].pb(i);
        for(int i=1;i<=M;i++)for(int j=1;j<=32;j++)if(i%j==0)ss[i]|=1<<j-1;
    }
    void ins(int x)
    {
        if(x<=32)
        {
            if(x<=8)for(int i=0;i<256;i++)r1[i]+=(i>>(x-1)&1);
            else if(x<=16)for(int i=0;i<256;i++)r2[i]+=(i>>(x-9)&1);
            else if(x<=24)for(int i=0;i<256;i++)r3[i]+=(i>>(x-17)&1);
            else for(int i=0;i<256;i++)r4[i]+=(i>>(x-25)&1);
        }
        else for(int i=x;i<=M;i+=x)b[i]++;
    }
    inline int calc(int x){x=ss[x];return r1[x&255]+r2[x>>8&255]+r3[x>>16&255]+r4[x>>24&255];}
    inline int sum(int x){return b[x]+c[x]+calc(x);}
    int main()
    {
        scanf("%d%d",&n,&m);init();
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=m;i++){scanf("%d%d",&q[i].l,&q[i].r);q[i].i=i;}
        sort(q+1,q+m+1,cmp);int l=1,r=0;
        for(int i=1;i<=m;i++)
        {
            if(l<q[i].l)g[r].pb((st){l,q[i].l-1,i<<1});else if(l>q[i].l)g[r].pb((st){q[i].l,l-1,i<<1});l=q[i].l;
            if(r<q[i].r)g[l-1].pb((st){r+1,q[i].r,i<<1|1});else if(r>q[i].r)g[l-1].pb((st){q[i].r+1,r,i<<1|1});r=q[i].r;
        }
        for(int i=1;i<=n;i++)
        {
            p1[i]=p1[i-1]+sum(a[i]);
            for(int j=0;j<V[a[i]].size();j++)c[V[a[i]][j]]++;
            ins(a[i]);p2[i]=p2[i-1]+sum(a[i]);
            for(int j=0;j<g[i].size();j++){st t=g[i][j];for(int k=t.l;k<=t.r;k++)res[t.i]+=sum(a[k]);} 
        }
        l=1,r=0;ll s=0;
        for(int i=1;i<=m;i++)
        {
            if(l<q[i].l)s+=p2[q[i].l-1]-p2[l-1]-res[i<<1];else if(l>q[i].l)s+=res[i<<1]+p2[q[i].l-1]-p2[l-1];l=q[i].l;
            if(r<q[i].r)s+=p1[q[i].r]-p1[r]-res[i<<1|1];else if(r>q[i].r)s+=res[i<<1|1]-p1[r]+p1[q[i].r];r=q[i].r;ans[q[i].i]=s+r-l+1;
        }
        for(int i=1;i<=m;i++)printf("%lld
    ",ans[i]);
        return 0;
    } 
  • 相关阅读:
    Hibernate之二级缓存
    Hibernate之HQL
    Hibernate 一对多自关联 多对多
    hibernate关联关系(一对多)
    Hibernate之主键生成策略
    Hibernate01
    struts的图片上传
    HashMap和HashTable本质性的区别
    集合03
    集合
  • 原文地址:https://www.cnblogs.com/alonefight/p/11005375.html
Copyright © 2011-2022 走看看