CF 121E - Lucky Array(树状数组裸题)

来源:互联网 发布:剑三男神捏脸数据 编辑:程序博客网 时间:2024/05/17 01:38

题目链接:http://codeforces.com/problemset/problem/121/E

题意:幸运数是指只由4,7组成的数,例如4,7,47,74,447……,这道题先给你n个数的数组,再给你m个操作,操作有两种:1、count l r(计算[l,r]区间内幸运数的总数,并输出结果);2、add l r d(区间内的每个数都加d)

思路:由于数组中每个数都小于104,所以只要现对于小于104的数判断是否是幸运数,再将是幸运数的数的每个子节点值赋值为1在求出区间和,区间和就是幸运数的总数

代码:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <queue>#define N 10005using namespace std;queue<int>q;int vis[N],in[N<<5],num[N<<5],n;void init(){    memset(vis,0,sizeof(vis));    while(!q.empty())        q.pop();q.push(0);while(q.front()<N){    vis[q.front()]=1;q.push(q.front()*10+4);q.push(q.front()*10+7);q.pop();}}int low_bit(int t){    return t&(-t);}int getSum(int end){    int sum=0;    while(end>0)    {        sum+=in[end];        end-=low_bit(end);    }    return sum;}void Add(int pos,int num){    while(pos<=n)    {        in[pos]+=num;        pos+=low_bit(pos);    }}int main(){    init();    int m,a,b,c,ans;    char s[10];    scanf("%d%d",&n,&m);    memset(in,0,sizeof(in));    for(int i=1;i<=n;i++)    {        scanf("%d",&num[i]);        if(vis[num[i]])            Add(i,1);    }    while(m--)    {        scanf("%s",s);        if(s[0]=='a')        {            scanf("%d%d%d",&a,&b,&c);            if(!c)                continue;            for(int i=a;i<=b;i++)            {                if(vis[num[i]])                    Add(i,-1);                num[i]+=c;                if(vis[num[i]])                    Add(i,1);            }        }        else        {            scanf("%d%d",&a,&b);            ans=getSum(b)-getSum(a-1);            printf("%d\n",ans);        }    }return 0;}


0 0
原创粉丝点击