jzoj4243 【五校联考6day1】c 分块

来源:互联网 发布:skycc营销软件客服 编辑:程序博客网 时间:2024/06/06 19:56

Description


定义S 为十进制只由4 和7 组成的全体正整数的集合。
对于1 ≤ i ≤ N,给定ai。要求完成M 个操作:
add l r v 将i ∈ [l, r] 的所有ai 加上v
count l r 统计有多少i 满足i ∈ [l, r] 且 ai ∈ S

Data Constraint


50% 的数据满足N,M ≤ 103
 100% 的数据满足1 ≤ N,M ≤ 105; 1 ≤ ai ≤ 104; 1 ≤ v ≤ 104
 数据保证所有操作结束后ai ≤ 104。

Solution


本蒟蒻第一题手写的分块,感慨一下
把序列分成n个块并维护每个块的桶。
对于一段(l,r)查询,暴力修改两端,中间的块就打标记
对于一段(l,r,v)修改,暴力修改两端,中间的块打标记
表示平衡树太jb难调了于是滚过来写点别的

Code


#include <stdio.h>#include <string.h>#include <math.h>#define rep(i,st,ed) for (int i=st;i<=ed;++i)#define fill(x,t) memset(x,t,sizeof(x))#define N 200005#define M 20005int rec[N],pos[N],add[N],a[N],s[N],e[N],t[501][M];int n,m;void read(int &x) {    x=0; int v=1; char ch=getchar();    for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());    for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());    x*=v;}void update(int x,int &y,int w) {    --t[x][y]; y+=w; ++t[x][y];}void prework() {    int st=1; rec[0]=0;    rec[++rec[0]]=4;    rec[++rec[0]]=7;    while (st<=rec[0]) {        int now=rec[st++];        if (now*10>=M) return;        rec[++rec[0]]=now*10+4;        rec[++rec[0]]=now*10+7;    }}void modify(int l,int r,int v) {    if (pos[l]==pos[r]) {        rep(i,l,r) update(pos[l],a[i],v);    } else {        rep(i,s[pos[r]],r) update(pos[r],a[i],v);        rep(i,l,e[pos[l]]) update(pos[l],a[i],v);        rep(i,pos[l]+1,pos[r]-1) add[i]+=v;    }}int query(int l,int r) {    int ret=0;    if (pos[l]==pos[r]) {        rep(i,l,r) {            rep(j,1,rec[0]) ret+=(a[i]+add[pos[l]])==rec[j];        }    } else {        rep(i,s[pos[r]],r) {            rep(j,1,rec[0]) ret+=(a[i]+add[pos[r]])==rec[j];        }        rep(i,l,e[pos[l]]) {            rep(j,1,rec[0]) ret+=(a[i]+add[pos[l]])==rec[j];        }        rep(i,pos[l]+1,pos[r]-1) {            rep(j,1,rec[0]) ret+=t[i][rec[j]-add[i]];        }    }    return ret;}int main(void) {    prework();    read(n); read(m);    int size=(int)(sqrt(n));    rep(i,1,n) {        read(a[i]);        pos[i]=(i-1)/size+1;        if (!s[pos[i]]) s[pos[i]]=i;        e[pos[i]]=i;        ++t[pos[i]][a[i]];    }    while (m--) {        char opt[5];        int l,r,v;        scanf("%s",opt);        if (opt[0]=='c') {            read(l); read(r);            printf("%d\n",query(l,r));        } else {            read(l); read(r); read(v);            modify(l,r,v);        }    }    return 0;}
原创粉丝点击