题意:从1开始操作,可以进行两种操作,第一种是乘以2,第二种是加1。让你求区间的总共的操作数。
思路:一个数从1开始操作,要想让操作次数最少,理所当然是要让乘以2的操作变多,所以我们可以倒着推一个数所需要的操作数,如果这个数是偶数,我们就让这个数除以2,然后操作数加1,如果这个数变为奇数了,我们就减1,操作数加1,让它变成偶数。
- 这题还需要注意一个点,就是这题会卡前缀和,我们在输入的时候就进行预处理,然后在查询的时候就可以节省很多时间。
题目链接:F. Building Numbers
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll flag = 0;
void f(ll x)
{
if(x == 1)
return ;
if(x%2 == 0)
{
flag++;
x /= 2;
f(x);
}
else
{
flag++;
x -= 1;
f(x);
}
}
int main()
{
int t,n,m;
scanf("%d",&t);
while(t--)
{
ll a[100010];
ll ans[100010];
ans[0] = 0;
scanf("%d %d",&n,&m);
for(int i = 1; i <= n; i++)
{
scanf("%lld",&a[i]);
flag = 0;
f(a[i]);
ans[i] = ans[i-1]+flag;
}
while(m--)
{
ll x,y;
scanf("%lld %lld",&x,&y);
printf("%lld\n",ans[y]-ans[x-1]);
}
}
return 0;
}