BZOJ 2506: calc【离线,值域分块
2016-11-14 21:16
357 查看
……看到这么鬼畜的不好维护的区间,考虑离线,从左到右添加数列中的数
因为值域是1e4,考虑p<=100和p>100的情况。
p<=100的情况下,O(√值域)地更新,O(1)地查询;p>100的时候,O(1)地更新,O(√值域)地查询
添加每个数的时候,对于p<=100的情况的贡献直接累加;对于p>100的显然只有100左右个数对答案有贡献,于是枚举就好了
……反正这种套路我应该学不会x
因为值域是1e4,考虑p<=100和p>100的情况。
p<=100的情况下,O(√值域)地更新,O(1)地查询;p>100的时候,O(1)地更新,O(√值域)地查询
添加每个数的时候,对于p<=100的情况的贡献直接累加;对于p>100的显然只有100左右个数对答案有贡献,于是枚举就好了
……反正这种套路我应该学不会x
#include<bits/stdc++.h> #define MAXN 100005 #define MX 10005 using namespace std; int n,m,mx; int a[MAXN]; struct t1{ int opt,pos,id,p,x; bool operator < (const t1 &ano) const{ return pos < ano.pos; } }Q[MAXN<<1]; int f1[105][105],f2[MX]; int ans[MAXN]; int read_l,read_r,read_p,read_x; int main(){ // freopen("1.in","r",stdin); scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) scanf("%d",a+i) , mx = max(mx,a[i]); for(int i=1;i<=m;++i){ scanf("%d%d%d%d",&read_l,&read_r,&read_p,&read_x); Q[i] = (t1){-1,read_l-1,i,read_p,read_x}; Q[i+m] = (t1){1,read_r,i,read_p,read_x}; } int m2 = m<<1; sort(Q+1,Q+m2+1); for(int i=1,now=0;i<=m2;++i){ while(now<Q[i].pos){ ++now; for(int j=1;j<=100;++j) ++f1[j][a[now]%j]; ++f2[a[now]]; } if(Q[i].p<=100) ans[Q[i].id] += Q[i].opt * f1[Q[i].p][Q[i].x]; else{ int tmp = 0; for(int j=Q[i].x;j<=mx;j+=Q[i].p) tmp += f2[j]; ans[Q[i].id] += Q[i].opt * tmp; } } for(int i=1;i<=m;++i) printf("%d\n",ans[i]); return 0; }
相关文章推荐
- BZOJ 2506: calc 权值分块
- 【bzoj 2506】calc(数论)
- bzoj 2506 calc 题解
- 【BZOJ2506】calc 分段+vector+莫队
- BZOJ 2506 calc
- 【bzoj2506】calc
- [BZOJ3626] LCA - 离线 - 树链剖分/动态树/分块
- bzoj2506 离线操作
- BZOJ 2506 calc
- BZOJ 3339 Rmq Problem【离线,值域线段树
- BZOJ2506 calc
- 【BZOJ 2738】 矩阵乘法|分块|离线
- BZOJ2506 calc
- BZOJ2506: calc
- BZOJ 2506 分块
- [bzoj2506] calc
- BZOJ2506 : calc
- [分块 阈值 离线] BZOJ 3351 [ioi2009]Regions
- 【BZOJ2506】calc
- bzoj 2743 树状数组+离线处理