Solution P12525 [Aboi Round 1] 私は雨

魔怔卡常题。/ll

考虑按照 \(p\) 根号分治。

\(p>B\),直接查询是 \(O(\frac{qV\log n}{B})\) 的。

不过可以对序列分块。对于整块预处理 \(c_{i,j}\) 表示前 \(i\) 个块 \(j\) 出现几次,每次询问时先把散块扫一遍丢到桶里,然后就可以做到 \(O(q\sqrt n+\frac{qV}{B})\) 了。

\(p\le B\),对每个 \(p\) 扫一遍整个数列预处理按 \(\bmod\space p\) 分类,这样每次询问相当于问一个矩阵内有多少个数。

还是分块!先转成查询左下角有多少个数。

考虑按下标分成 \(X\) 块,散块直接扫一遍 \(O(\frac{n}{X})\) 就能知道答案。但这样子整块还是做不了,因为要存储的信息有 \(O(VBX)\) 级别。

再次分块!将值域也分成 \(Y\) 块,此时对于超出整块的部分,我们按照上面 \(p>B\) 时的单值查出现次数做。此时下标和值都被分成了若干块,一共只有 \(O(\frac{nV}{XY})\) 个块。此时再对这些块做前缀和然后查询即可。

整理一下时间复杂度,是 \(O(q\sqrt n+\frac{qV}{B}+\frac{qn}{X}+\frac{qV}{Y}+\frac{nVB}{XY})\),取 \(X=\sqrt n,Y=\sqrt V,B=\sqrt V\),可得时间复杂度 \(O(q\sqrt n+q\sqrt V+q\sqrt n+V\sqrt n)\)

由于 \(n,q,V\) 实际上可以视为同阶,大概可以认为时间复杂度为 \(O(n\sqrt n)\),空间复杂度也为 \(O(n\sqrt n)\)

卡常技巧:由于另一维是预处理,查询是 \(O(1)\) 的,因此可以适当减小块长。最后卡到了 1.51s 上下,靠评测机波动并非顺利通过。

// Code by UniGravity
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define forto(i,a,b) for(int i=(a),_##i(b);i<=_##i;i++)
#define forbk(i,a,b) for(int i=(a),_##i(b);i>=_##i;i--)
#define forv(i,a) for(int i(0),_##i(a);i<_##i;i++)
#define fst first
#define snd second
#define il inline
#define eb emplace_back
#define mkp make_pair
using namespace std;
char *p1,*p2,buf[1<<20];
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
il int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||'9'<c)c=='-'?(f=-1):0,c=getchar();
    while('0'<=c&&c<='9')x=x*10+c-'0',c=getchar();
    return x*f;
}

const int N=100005,M=200005,X=300,Y=360,B=350;
int n,m=200000,tp,a[N];
il int dceil(int x,int y){return x<=0?0:((x-1)/y+1);}
int ib[N],ibg[N/X+2],ied[N/X+2],vb[M],vbg[M/Y+2],ved[M/Y+2];

namespace ID{
    int c[N/X+2][M];
    il void init(){
        forto(i,1,n){
            ib[i]=(i-1)/X+1,c[ib[i]][a[i]]++;
            if(!ibg[ib[i]])ibg[ib[i]]=i;
            ied[ib[i]]=i;
        }
        forto(i,1,m){
            vb[i]=(i-1)/Y+1;
            if(!vbg[vb[i]])vbg[vb[i]]=i;
            ved[vb[i]]=i;
        }
        forto(i,1,ib[n])forto(j,1,m)c[i][j]+=c[i-1][j];
    }
    int cnt[M],nl,nr;
    il void qset(int l,int r){
        if(ib[l]==ib[r]){
            nl=nr=0;
            forto(i,l,r)cnt[a[i]]++;
        }else{
            nl=ib[l],nr=ib[r]-1;
            forto(i,l,ied[ib[l]])cnt[a[i]]++;
            forto(i,ibg[ib[r]],r)cnt[a[i]]++;
        }
    }
    il void qreset(int l,int r){
        if(ib[l]==ib[r]){
            forto(i,l,r)cnt[a[i]]--;
        }else{
            forto(i,l,ied[ib[l]])cnt[a[i]]--;
            forto(i,ibg[ib[r]],r)cnt[a[i]]--;
        }
    }
    il int qry(int val){
        return cnt[val]+c[nr][val]-c[nl][val];
    }
}

int sum[B+2][N/X+2][M/Y+2],reval[B+2][M];
vector<int>len[B+2];
il int getv(int p,int x){
    if(x%p==0)return x/p;
    else return len[p][x%p-1]+x/p+1;
}

signed main(){
    n=read(),tp=read();
    forto(i,1,n)a[i]=read();
    ID::init();
    forto(p,1,B){
        len[p].resize(p+1),len[p][0]=m/p;
        forto(i,1,p-1)len[p][i]=len[p][i-1]+(m-i)/p+1;
        int tot=0;
        forv(c,p)for(int i=(!c)?p:c;i<=m;i+=p)reval[p][++tot]=i;
        forto(i,1,n)sum[p][ib[i]][vb[getv(p,a[i])]]++;
        forto(i,1,ib[n])forto(j,1,vb[m])sum[p][i][j]+=sum[p][i-1][j]+sum[p][i][j-1]-sum[p][i-1][j-1];
    }
    int q=read(),l,r,bg,ed,p,x,lst=0,res,vi,vj,nl,nr,tmp;
    forto(_,1,q){
        l=read()^lst,r=read()^lst,bg=read()^lst,ed=read()^lst,p=read()^lst,x=read()^lst;
        res=0,ID::qset(l,r);
        if(p>B){
            for(int i=dceil(bg-x,p)*p+x;i<=ed;i+=p)res+=ID::qry(i);
        }else{
            vi=dceil(bg-x,p)*p+x,vj=ed-x<0?-1:((ed-x)/p*p+x);
            if(vi<=vj){
                vi=getv(p,vi),vj=getv(p,vj);
                if(vb[vi]==vb[vj]){
                    forto(i,vi,vj)res+=ID::qry(reval[p][i]);
                }else{
                    forto(i,vi,ved[vb[vi]])res+=ID::qry(reval[p][i]);
                    forto(i,vbg[vb[vj]],vj)res+=ID::qry(reval[p][i]);
                    vi=ved[vb[vi]]+1,vj=vbg[vb[vj]]-1;
                    if(vi<=vj){
                        if(ib[l]==ib[r]){
                            forto(i,l,r)tmp=getv(p,a[i]),res+=(vi<=tmp&&tmp<=vj);
                        }else{
                            forto(i,l,ied[ib[l]])tmp=getv(p,a[i]),res+=(vi<=tmp&&tmp<=vj);
                            forto(i,ibg[ib[r]],r)tmp=getv(p,a[i]),res+=(vi<=tmp&&tmp<=vj);
                            nl=ib[l]+1,nr=ib[r]-1,vi=vb[vi],vj=vb[vj];
                            if(nl<=nr)res+=sum[p][nr][vj]-sum[p][nl-1][vj]-sum[p][nr][vi-1]+sum[p][nl-1][vi-1];
                        }
                    }
                }
            }
        }
        ID::qreset(l,r);
        if(tp)lst=res;
        printf("%d\n",res);
    }
    return 0;
}
posted @ 2025-05-27 17:30  UniGravity_qwq  阅读(19)  评论(0)    收藏  举报