HDU - 5975 Aninteresting game lowbit 和 转化二进制

Let’s play a game.We add numbers 1,2...n in increasing order from 1 and put them into some sets.
When we add i,we must create a new set, and put iinto it.And meanwhile we have to bring [i-lowbit(i)+1,i-1] from their original sets, and put them into the new set,too.When we put one integer into a set,it costs us one unit physical strength. But bringing integer from old set does not cost any physical strength.
After we add 1,2...n,we have q queries now.There are two different kinds of query:
1 L R:query the cost of strength after we add all of [L,R](1≤L≤R≤n)
2 x:query the units of strength we cost for putting x(1≤x≤n) into some sets.

Input

There are several cases,process till end of the input.
For each case,the first line contains two integers n and q.Then q lines follow.Each line contains one query.The form of query has been shown above.
n≤10^18,q≤10^5

Output

For each query, please output one line containing your answer for this query

Sample Input

10 2
1 8 9
2 6

Sample Output

9
2

题解:这个题的意思是 op==1时 计算区间内 lowbit(x) 的加和 按二进制的每一位进行计算,第y位为1的数的个数就为 n/(1<<(y-1)) - n/(1<<y)  因为是这一位倍数的 如果这一位为0 那么就是比这一位高一位的倍数,减去就可以了 然后在成对应每位的大小就可以了

#include<iostream>
#include<cstdio>
using namespace std;
#define lowbit(x) x&(-x)
typedef long long ll;
ll n,q;
ll cul(ll x)
{
    ll ans=0;
    for(ll i=1;i<=x;i*=2)
        ans+=(x/i-x/i/2)*i;
    return ans;
}
ll cul_(ll x)
{
    ll ans=0;
    while(x<=n)
    {
        ans++;
        x+=lowbit(x);
    }
    return ans;
}
int main()
{
    while(~scanf("%lld%lld",&n,&q))
    {
        ll op,l,r;
        while(q--)
        {
            scanf("%lld",&op);
            if(op==1)
            {
                scanf("%lld%lld",&l,&r);
                printf("%lld\n",cul(r)-cul(l-1));
            }
            else
            {
                scanf("%lld",&l);
                printf("%lld\n",cul_(l));
            }
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值