hdu 5975 树状数组原理题(2016ACM/ICPC亚洲区大连站)

来源:互联网 发布:淘宝联盟分享赚 实操 编辑:程序博客网 时间:2024/05/18 06:00

题目大意:每次加入一个数新的i,是把[i-lowbit(i)+1,i]的数字都加入集合。每把一个数加入到一个集合内,都要花费一单位能量。统计花费的能量数。

操作1:把[L,R]的数字依此加入,统计出所有的能量话费。

操作2:询问一个X,查询X在1~n的插入中一共被移动了多少次。

思路:

直接算:

long long ans = 0;                for(int i=a;i<=b;i++)                    ans+=lowbit(i);                cout<<ans<<endl;
这样会TLE。

操作1:树状数组的原理相当于每个位置放的都是1,奇数位都是1,偶数根据所在位置,依此为2,4,8,16。。。

所以,只需转化为二进制后第0位知道第n位1出现的个数,再乘对应的2,4,8。。。就好了。

ll get_ans(ll x){    ll ans = 0,t = 1,tt;    for(int i=0;(t<<i)<=x;i++)    {        tt = x/(t<<i);        tt -= x/(t<<(i+1));        tt *= (t<<i);        ans += tt;        //cout<<ans<<' ';    }    //cout<<endl;    return ans;}

操作2:

考虑树状数组,转化为x被树状数组中1-n的下标中哪些所覆盖了,直接累加lowbit就行。

(7=111,

那么lowbit为1的有几个?

001,011,101,111

奇数为(n+1)>>1;

偶数为n>>1;)

while(a<=n)                {                    ans++;                    a += lowbit(a);                }

////  main.cpp//  160929////  Created by 刘哲 on 17/5/30.//  Copyright © 2016年 my_code. All rights reserved.//#include <bits/stdc++.h>#include <iostream>#include <algorithm>#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <string.h>#include <map>#include <set>#include <queue>#include <deque>#include <list>#include <bitset>#include <stack>#include <stdlib.h>#define lowbit(x) (x&-x)typedef long long ll;typedef long long LL;using namespace std;ll get_ans(ll x){    ll ans = 0,t = 1,tt;    for(int i=0;(t<<i)<=x;i++)    {        tt = x/(t<<i);        tt -= x/(t<<(i+1));        tt *= (t<<i);        ans += tt;        //cout<<ans<<' ';    }    //cout<<endl;    return ans;}int main(){    //get_ans(9);    ll n,q;    int op;    ll a,b;   // while(cin>>n>>q)    while(~scanf("%lld%lld",&n,&q))    {        while(q--)        {            //cin>>op;            scanf("%d",&op);            if(op==1)            {                ll ans = 0;                //cin>>a>>b;                scanf("%lld%lld",&a,&b);                ans = get_ans(b)-get_ans(a-1);                //cout<<ans<<endl;                printf("%lld\n",ans);            }            else            {                ll ans = 0;                //cin>>a;                scanf("%lld",&a);                while(a<=n)                {                    ans++;                    a += lowbit(a);                }                //cout<<ans<<endl;                printf("%lld\n",ans);            }        }    }    return 0;}


阅读全文
0 0