训练赛-Building Numbers

题意:首先告诉你,一个数字从1开始有两种变换方式:1.当前数字的值加1

2.当前的数字值乘2;

思路:首先把数组里的数字需要的变换次数算出来,然后用前缀和解决;

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;
ll a[100005];ll sum[100005];ll ans[100005];
int main()
{
    int t;
    int n;
    int q;
    scanf("%d",&t);
    int l,r;
    while(t--)
    {
        memset(sum,0,sizeof(sum));
        memset(ans,0,sizeof(ans));
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            ll x=a[i];
            if(x==1)
            {
                ans[i]=0;continue;
            }
            while(x>1)
            {
               if((x&1)==1)
               {
                    x--;ans[i]++;
               }
               else
               {
                   x=x/2;ans[i]++;
               }
            }
        }
        for(int i=1;i<=n;i++)
            sum[i]=sum[i-1]+ans[i];
        while(q--)
        {
            scanf("%d%d",&l,&r);
            if(l==r)
                printf("%lld\n",ans[l]);
            else
                printf("%lld\n",sum[r]-sum[l-1]);
        }
    }
    return 0;
}

 

posted @ 2018-01-24 19:03  荒岛的龟  阅读(129)  评论(0编辑  收藏  举报