分块&莫队模板

最裸的莫队https://www.luogu.org/problemnew/show/P1494

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e4+99;
struct query{int l,r,id;ll a,b;}q[N];
int n,m,block,c[N],pos[N];
ll s[N],ans;
bool cmp(query a,query b){return pos[a.l]<pos[b.l]||pos[a.l]==pos[b.l]&&a.r<b.r;}
bool cmd(query a,query b){return a.id<b.id;}
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
void update(int p,int add)
{
    ans-=s[c[p]]*s[c[p]];
    s[c[p]]+=add;
    ans+=s[c[p]]*s[c[p]];
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&c[i]);
    for(int i=1;i<=m;i++)scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
    block=floor(sqrt(n)+0.01);
    for(int i=1;i<=n;i++)pos[i]=(i-1)/block+1;
    sort(q+1,q+m+1,cmp);
    for(int i=1,l=1,r=0;i<=m;i++)
    {
        while(r<q[i].r)update(++r,1);
        while(r>q[i].r)update(r--,-1);
        while(l<q[i].l)update(l++,-1);
        while(l>q[i].l)update(--l,1);
        if(q[i].l==q[i].r){q[i].a=0;q[i].b=1;continue;}
        q[i].a=ans-(r-l+1);
        q[i].b=(ll)(r-l+1)*(r-l);
        ll t=gcd(q[i].a,q[i].b);
        q[i].a/=t;q[i].b/=t;
    }
    sort(q+1,q+m+1,cmd);
    for(int i=1;i<=m;i++)printf("%lld/%lld
",q[i].a,q[i].b);
}

树上莫队https://www.luogu.org/problemnew/show/P4074

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+99;
struct modify{int x,y,z;}p[N];
struct query{int l,r,k,lca,id;}q[N];
struct edge{int v,nxt;}e[N*2];
int n,m,Q,block,cnt,mdf,qry,hd[N],v[N],w[N],fa[N][20],deep[N],sum[N],pos[N],st[N],ed[N],col[N],dfx[N],lst[N];
ll ans[N],ret;
bool vis[N];
bool cmp(query x,query y)
{
    if(pos[x.l]!=pos[y.l])return pos[x.l]<pos[y.l];
    if(pos[x.r]!=pos[y.r])return pos[x.r]<pos[y.r];
    return x.k<y.k;
}
void add(int x,int y){e[++cnt]=(edge){y,hd[x]};hd[x]=cnt;}
void dfs(int u)
{
    st[u]=++cnt;dfx[cnt]=u;
    for(int i=hd[u];i;i=e[i].nxt)
    if(e[i].v!=fa[u][0])
    fa[e[i].v][0]=u,deep[e[i].v]=deep[u]+1,dfs(e[i].v);
    ed[u]=++cnt;dfx[cnt]=u;
}
int lca(int x,int y)
{
    if(deep[x]<deep[y])swap(x,y);
    int t=deep[x]-deep[y];
    for(int i=0;(1<<i)<=t;i++)if(t&(1<<i))x=fa[x][i];
    if(x==y)return x;
    for(int i=19;i>=0;i--)
    if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
    return fa[x][0];
}
void update(int x)
{
    vis[x]^=1;
    if(vis[x])sum[col[x]]++,ret+=1ll*v[col[x]]*w[sum[col[x]]];
    else ret-=1ll*v[col[x]]*w[sum[col[x]]],sum[col[x]]--;
}
void change(int x,int y)
{
    if(vis[x])update(x),col[x]=y,update(x);
    else col[x]=y;
    return;
}
int main()
{
    scanf("%d%d%d",&n,&m,&Q);
    block=pow(n,2.0/3)*0.52;
    for(int i=1;i<=m;i++)scanf("%d",&v[i]);
    for(int i=1;i<=n;i++)scanf("%d",&w[i]);
    for(int i=1,x,y;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x);
    for(int i=1;i<=n;i++)scanf("%d",&col[i]),lst[i]=col[i];
    cnt=0;dfs(1);
    for(int j=1;(1<<j)<=n;j++)
    for(int i=1;i<=n;i++)
    fa[i][j]=fa[fa[i][j-1]][j-1];
    for(int i=1;i<=2*n;i++)pos[i]=i/block+1;
    for(int i=1,op,x,y;i<=Q;i++)
    {
        scanf("%d%d%d",&op,&x,&y);
        if(!op)p[++mdf]=(modify){x,lst[x],y},lst[x]=y;
        else{
            if(st[x]>st[y])swap(x,y);
            int Fa=lca(x,y);
            if(x==Fa)q[++qry]=(query){st[x],st[y],mdf,0,qry};
            else q[++qry]=(query){ed[x],st[y],mdf,Fa,qry};
        }
    }
    sort(q+1,q+qry+1,cmp);
    for(int i=1,l=1,r=0,k=0;i<=qry;i++)
    {
        while(k<q[i].k)k++,change(p[k].x,p[k].z);
        while(k>q[i].k)change(p[k].x,p[k].y),k--;
        while(l>q[i].l)update(dfx[--l]);
        while(l<q[i].l)update(dfx[l++]);
        while(r<q[i].r)update(dfx[++r]);
        while(r>q[i].r)update(dfx[r--]);
        if(q[i].lca)update(q[i].lca);
        ans[q[i].id]=ret;
        if(q[i].lca)update(q[i].lca);
    }
    for(int i=1;i<=qry;i++)printf("%lld
",ans[i]);
}

带修莫队https://www.lydsy.com/JudgeOnline/problem.php?id=2120

#include<bits/stdc++.h>
using namespace std;
const int N=5e4+99;
int n,m,cntq,cntc,block,a[N],pos[N],t[N],ret,ans[N],l,r,tim,cnt[N*20];
struct query{
    int l,r,tm,id;
    bool operator<(const query&b)const
    {
        if(pos[l]!=pos[b.l])return pos[l]<pos[b.l];
        if(pos[r]!=pos[b.r])return pos[r]<pos[b.r];
        return tm<b.tm;
    }
}q[N];
struct change{int x,ya,yb;}c[N];
void add(int p){if(!cnt[p])ret++;cnt[p]++;}
void del(int p){cnt[p]--;if(!cnt[p])ret--;}
void update1(change c)
{if(l<=c.x&&c.x<=r)del(c.yb),add(c.ya);a[c.x]=c.ya;}
void update2(change c)
{if(l<=c.x&&c.x<=r)del(c.ya),add(c.yb);a[c.x]=c.yb;}
int main()
{
    scanf("%d%d",&n,&m);
    block=floor(sqrt(n)+0.01);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),t[i]=a[i],pos[i]=(i-1)/block+1;
    int x,y;char ch;
    for(int i=0;i<m;i++)
    {
        scanf(" %c%d%d",&ch,&x,&y);
        if(ch=='R')c[++cntc]={x,y,t[x]},t[x]=y;
        else q[++cntq]={x,y,cntc,cntq};
    }
    sort(q+1,q+cntq+1);
    l=1,r=0,tim=0;
    for(int i=1;i<=cntq;i++)
    {
        while(tim<q[i].tm)update1(c[++tim]);
        while(tim>q[i].tm)update2(c[tim--]);
        while(r<q[i].r)add(a[++r]);
        while(r>q[i].r)del(a[r--]);
        while(l<q[i].l)del(a[l++]);
        while(l>q[i].l)add(a[--l]);
        ans[q[i].id]=ret;
    }
    for(int i=1;i<=cntq;i++)printf("%d
",ans[i]);
}

回滚莫队https://www.lydsy.com/JudgeOnline/problem.php?id=4241

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+99;
struct query{int l,r,id;}q[N];
int n,m,len,block,pos[N],a[N],v[N],num[N],num1[N];
ll ret,ans[N];
bool cmp(query x,query y){return pos[x.l]==pos[y.l]?x.r<y.r:pos[x.l]<pos[y.l];}
void add(int p){ret=max(ret,1ll*(++num[p])*v[p]);}
void del(int p){--num[p];}
ll query(int l,int r)
{
    ll mx=0;
    for(int i=l;i<=r;i++)mx=max(mx,1ll*(++num1[a[i]])*v[a[i]]);
    for(int i=l;i<=r;i++)--num1[a[i]];
    return mx;
}
int update(int i,int blo)
{
    int r=min(blo*block,n),l=r+1,L=l;
    memset(num,0,sizeof num);
    ret=0;
    for(;pos[q[i].l]==blo;i++)
    {
        if(pos[q[i].l]==pos[q[i].r])ans[q[i].id]=query(q[i].l,q[i].r);
        else{
            while(r<q[i].r)add(a[++r]);
            ll tmp=ret;
            while(l>q[i].l)add(a[--l]);
            ans[q[i].id]=ret;
            while(l<L)del(a[l++]);
            ret=tmp;
        }
    }
    return i;
}
int main()
{
    scanf("%d%d",&n,&m);
    block=sqrt(n+1);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),v[i]=a[i],pos[i]=(i-1)/block+1;
    sort(v+1,v+n+1);
    len=unique(v+1,v+n+1)-v-1;
    for(int i=1;i<=n;i++)a[i]=lower_bound(v+1,v+len+1,a[i])-v;
    for(int i=1;i<=m;i++)scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
    sort(q+1,q+m+1,cmp);
    for(int now=1,i=1;i<=pos[n];i++)now=update(now,i);
    for(int i=1;i<=m;i++)printf("%lld
",ans[i]);
}

二维莫队https://www.lydsy.com/JudgeOnline/problem.php?id=2639

#include<bits/stdc++.h>
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define y1 orz
using namespace std;
const int N=202,M=1e5;
int n,m,Q,tot,sum,x1,y1,x2,y2,a[N][N],b[N*N],bel[N],cnt[N*N],ans[M];
struct query{
    int x1,y1,x2,y2,id;
    bool operator<(const query&a)const{
        if(bel[x1]!=bel[a.x1])return x1<a.x1;
        if(bel[y1]!=bel[a.y1])return y1<a.y1;
        if(bel[x2]!=bel[a.x2])return x2<a.x2;
        return y2<a.y2;
    }
}q[M];
int sqr(int x){return x*x;}
inline void modify_x(int x,int v)
{rep(i,y1,y2)sum-=sqr(cnt[a[x][i]]),cnt[a[x][i]]+=v,sum+=sqr(cnt[a[x][i]]);}
inline void modify_y(int y,int v)
{rep(i,x1,x2)sum-=sqr(cnt[a[i][y]]),cnt[a[i][y]]+=v,sum+=sqr(cnt[a[i][y]]);}
int main()
{
    scanf("%d%d",&n,&m);
    rep(i,1,max(n,m))bel[i]=i/12;
    rep(i,1,n)rep(j,1,m)scanf("%d",&a[i][j]),b[++tot]=a[i][j];
    sort(b+1,b+tot+1);
    tot=unique(b+1,b+tot+1)-b-1;
    rep(i,1,n)rep(j,1,m)a[i][j]=lower_bound(b+1,b+tot+1,a[i][j])-b;
    scanf("%d",&Q);
    rep(i,1,Q)
    {
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        if(x1>x2)swap(x1,x2);if(y1>y2)swap(y1,y2);
        q[i]=(query){x1,y1,x2,y2,i};
    }
    sort(q+1,q+Q+1);
    x1=1,y1=1,x2=0,y2=0;
    rep(i,1,Q)
    {
        while(x1>q[i].x1)modify_x(--x1,1);
        while(x2<q[i].x2)modify_x(++x2,1);
        while(x1<q[i].x1)modify_x(x1++,-1);
        while(x2>q[i].x2)modify_x(x2--,-1);
        while(y1>q[i].y1)modify_y(--y1,1);
        while(y2<q[i].y2)modify_y(++y2,1);
        while(y1<q[i].y1)modify_y(y1++,-1);
        while(y2>q[i].y2)modify_y(y2--,-1);
        ans[q[i].id]=sum;
    }
    rep(i,1,Q)printf("%d
",ans[i]);
}

按位分块https://www.luogu.org/problemnew/show/CF472G

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7;
int n1,n2,m,sz[65536];
unsigned a[32][N],b[32][N];
char s[N];
int count(unsigned x){return sz[x>>16]+sz[x&65535];}
int main()
{
    scanf("%s",s),n1=strlen(s);
    for(int j=0;j<32;j++)for(int i=0;i+j<n1;i++)a[j][i>>5]|=s[i+j]=='1'?1<<(i&31):0;
    scanf("%s",s),n2=strlen(s);
    for(int j=0;j<32;j++)for(int i=0;i+j<n2;i++)b[j][i>>5]|=s[i+j]=='1'?1<<(i&31):0;
    for(int i=0;i<65536;i++)sz[i]=sz[i>>1]+(i&1);
    scanf("%d",&m);
    while(m--)
    {
        int x,y,len,ans=0,i,j;
        scanf("%d%d%d",&x,&y,&len);
        for(i=x>>5,j=y>>5;len>=32;i++,j++,len-=32)ans+=count(a[x&31][i]^b[y&31][j]);
        ans+=count((a[x&31][i]^b[y&31][j])&((1<<len)-1));
        printf("%d
",ans);
    }
}

块状链表:咕

原文地址:https://www.cnblogs.com/hfctf0210/p/11039301.html