CF 121E - Lucky Array(樹狀數組裸題)

題目鏈接: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 10005
using 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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章