[BZOJ2906] 分块

[BZOJ2906]

 

  • 预处理出锅zbl
  • 预处理f[i][j][k],g[i][j][k]分别表示第i块到第j块 k的出现次数和小于等于k的数的出现次数的平方和
  • 查询的时候加上块外数的贡献即可
  • 小trick:计算出每块的起始位置和终止位置
  • 计算分块的大小时不要用除法,否则会RE

Code


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define ll long long
using namespace std;
const int N=5e4+10;
int blo,st[N],ed[N],cnt[20010],a[N],bl[N],f[41][41][20010];
ll g[41][41][20001],l,r,c,d,n,m,q;
ll work(int l,int r,int c,int d){
    ll ans=0;
    if(bl[l]==bl[r]||bl[l]==bl[r]-1){
        rep(i,l,r){
            if(a[i]>=c&&a[i]<=d){
                cnt[a[i]]++;
            }
        }
        rep(i,l,r){
            if(a[i]>=c&&a[i]<=d){
                ans+=1LL*cnt[a[i]]*cnt[a[i]];
                cnt[a[i]]=0;
            }
        }
    }else{
        rep(i,l,blo*bl[l]) if(a[i]>=c&&a[i]<=d) cnt[a[i]]++;
        rep(i,(bl[r]-1)*blo+1,r) if(a[i]>=c&&a[i]<=d) cnt[a[i]]++;
        rep(i,l,blo*bl[l]){
            if(a[i]>=c&&a[i]<=d){
                int num=f[bl[l]+1][bl[r]-1][a[i]];
                ans+=1LL*2*num*cnt[a[i]]+1LL*cnt[a[i]]*cnt[a[i]];
                cnt[a[i]]=0;
            }
        }
        rep(i,(bl[r]-1)*blo+1,r){
            if(a[i]>=c&&a[i]<=d){
                int num=f[bl[l]+1][bl[r]-1][a[i]];
                ans+=1LL*2*num*cnt[a[i]]+1LL*cnt[a[i]]*cnt[a[i]];
                cnt[a[i]]=0;
            }
        }
        ans+=g[bl[l]+1][bl[r]-1][d]-g[bl[l]+1][bl[r]-1][c-1];
    }
    return ans;
}
int main()
{
    scanf("%lld%lld%lld",&n,&m,&q); blo=pow(n,0.6666666);
    rep(i,1,n)scanf("%d",&a[i]);
    rep(i,1,n){
        bl[i]=(i-1)/blo+1;
	if(!st[bl[i]])st[bl[i]]=i;
	ed[bl[i]]=i;
    }
    rep(i,1,bl[n])
        rep(j,i,bl[n])
	    rep(k,st[i],ed[j])
		f[i][j][a[k]]++;//就是这里写挂了
    rep(i,1,bl[n])
        rep(j,i,bl[n])
            rep(k,1,m)
                g[i][j][k]=g[i][j][k-1]+(ll)f[i][j][k]*f[i][j][k];//就是这里写挂了
    ll ans=0;
    while(q--){
        scanf("%lld%lld%lld%lld",&l,&r,&c,&d);
        l^=ans,r^=ans,c^=ans,d^=ans;
        ans=work(l,r,c,d);
        printf("%lld\n",ans);
    }return 0;
}

 

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页

打赏

ShɑΙteж

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者