jzoj 4243. 【五校联考6day1】c 分块

来源:互联网 发布:云计算和分布式计算 编辑:程序博客网 时间:2024/06/07 02:43

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

Input

第一行:两个正整数N、M。
第二行:N 个正整数代表ai。
之后M 行:每行代表一个操作。

Output

 对于每个count 操作输出一行:一个整数代表答案。

Sample Input

3 62 3 4count 1 3count 1 2add 1 3 2count 1 3add 2 3 3count 1 3

Sample Output

1011

Data Constraint

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


分析:这是本蒟蒻第一次打分块,因为不熟练所以调了n久,调了一晚最后发现原来是数组开小了!

把序列分成根号n块

对于每个块维护一个桶

对于add操作多余块暴力修改其余块加标记

对于查询操作同上


代码:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath>#define ll long long#define inf 0x7fffffff#define N 100005using namespace std;int n,m,block,sblock,sw,w[40],pos[N],a[N],t[1000][100005],add[1000],s[1000],e[1000];void work(){for (int i=1;i<=10000;i++){int flag=0,j=i;while (j){if (j%10!=4&&j%10!=7) {flag=1;break;}j/=10;}if (!flag) w[++sw]=i;}}void reset(){for (int i=1;i<=n;i++)t[pos[i]][a[i]]++;}void updata(int x,int y,int z){if (pos[x]==pos[y])for (int i=x;i<=y;i++){t[pos[x]][a[i]]--;a[i]+=z;t[pos[x]][a[i]]++;}else{for (int i=x;i<=e[pos[x]];i++){t[pos[x]][a[i]]--;a[i]+=z;t[pos[x]][a[i]]++;}for (int i=s[pos[y]];i<=y;i++){t[pos[y]][a[i]]--;a[i]+=z;t[pos[y]][a[i]]++;}for (int i=pos[x]+1;i<pos[y];i++)add[i]+=z;}}int query(int x,int y){int ans=0;if (pos[x]==pos[y]){for (int i=x;i<=y;i++)for (int j=1;j<=sw;j++)if (a[i]+add[pos[x]]==w[j]) ans++;return ans;}else{for (int i=x;i<=e[pos[x]];i++)for (int j=1;j<=sw;j++)if (a[i]+add[pos[x]]==w[j]) ans++;for (int i=s[pos[y]];i<=y;i++)for (int j=1;j<=sw;j++)if (a[i]+add[pos[y]]==w[j]) ans++;for (int i=pos[x]+1;i<pos[y];i++)for (int j=1;j<=sw;j++)ans+=t[i][w[j]-add[i]];return ans;}}int main(){work();scanf("%d%d",&n,&m);block=int(sqrt(n));for (int i=1;i<=n;i++){scanf("%d",&a[i]);pos[i]=(i-1)/block+1;if (s[pos[i]]==0) s[pos[i]]=i;e[pos[i]]=i;}sblock=(n+block-1)/block;reset();char ch[10];for (int i=1;i<=m;i++){scanf("%s",ch);if (ch[0]=='a') {int x,y,z;scanf("%d%d%d",&x,&y,&z);updata(x,y,z);}else{int x,y;scanf("%d%d",&x,&y);printf("%d\n",query(x,y));}}return 0;}


0 0