zoukankan      html  css  js  c++  java
  • 分块&莫队模板

    最裸的莫队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);
        }
    }

    块状链表:咕

  • 相关阅读:
    c#读sql server数据添加到MySQL数据库
    ASP.NET取得Request URL的各个部分
    jquery,attr,prop,checkbox标签已有checked=checked但是不显示勾选
    ASP.NET 4.0 :MasterPage母版页的ClientIDMode属性
    百度地图 根据坐标,获取省份,城市,区域
    ECharts
    SQL 更新修改删除一个表,库存自动增减的写法
    ajaxFileupload 多文件上传
    JSON C# Class Generator ---由json字符串生成C#实体类的工具
    mvc 部署到iis 提示错误未能加载文件或程序集System.Web.Http.WebHost
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/11039301.html
Copyright © 2011-2022 走看看