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.
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
For each query, please output one line containing your answer for this query
10 2
1 8 9
2 6
9
2
lowbit(i) =i&(-i).It means the size of the lowest nonzero bits in binary of i. For example, 610=1102, lowbit(6) =102= 210
When we add 8,we should bring [1,7] and 8 into new set.
When we add 9,we should bring [9,8] (empty) and 9 into new set.
So the first answer is 8+1=9.
When we add 6 and 8,we should put 6 into new sets.
So the second answer is 2.
query1要求移动一个区间内的数的花费总和。query要求在移动1~n的过程中,数字x被移动的次数。
query1即求lowbit数组的前缀和,可以先写出1~10的二进制表示,找到规律,这样对于某个特定的数,只需要枚举它的每个二进制位即可。query2同样可以根据简单的例子找到规律,就是参照树状数组单点修改的过程,求出这个过程中lowbit数组的转移次数。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
#define ull unsigned long long
#define db double
//#define rep(i,n) for(int i = 0;i < n; i++)
//#define rep(i,n) for(int i = 0;i < n; i++)
#define rep(i,a,b) for (int i=(a),_ed=(b);i<=_ed;i++)
//#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define fil(a,b) memset((a),(b),sizeof(a))
#define cl(a) fil(a,0)
#define pb push_back
#define mp make_pair
#define exp 2.7182818
#define PI 3.141592653589793238462643383279502884
#define inf 0x3f3f3f3f
#define fi first
#define se second
#define eps 1e-6
#define MOD 1000000007ll
using namespace std;
ll n;
int lowbit(int x) {return x&(-x);}
ll lowbit(ll x) {return x&(-x);}
ll cal(ll x)
{
ll res=0;
ll test=x;
int xx=0;
while(test)
{
xx++;
test>>=1;
}
for(int i=1;i<=xx;++i)
{
ll group=(x+1)/(1ll<1ll<<(i-1));
ll remain=((ll)x+1)-(group*(1ll<0ll,remain-(1ll<<(i-1)));
if(remain>0ll) res+=(1ll<<(i-1));
}
return res;
}
int process(ll x)
{
int step=0;
while(x<=n)
{
step++;
x+=lowbit(x);
}
return step;
}
int main(void)
{
//freopen("input.in","r",stdin);
//freopen("output.out","w",stdout);
int q;
int op;
ll from,to,x;
while(scanf("%lld%d",&n,&q)!=EOF)
{
for(int i=1;i<=q;++i)
{
scanf("%d",&op);
if(op==1)
{
scanf("%lld%lld",&from,&to);
printf("%lld\n",cal(to)-cal(from-1));
}
else
{
scanf("%lld",&x);
printf("%d\n",process(x));
}
}
}
return 0;
}