训练赛-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; }