hdu 5975 树状数组原理题(2016ACM/ICPC亚洲区大连站)
2017-06-09 16:34
429 查看
题目大意:每次加入一个数新的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);
}
操作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; }
相关文章推荐
- hdu 5971 Wrestling Match 判断能否构成二分图 [Problem A]2016ACM/ICPC亚洲区大连站
- Wrestling Match 2016ACM/ICPC亚洲区大连站-重现赛(感谢大连海事大学)hdu 5971
- HDU 5979 Convex【计算几何】 (2016ACM/ICPC亚洲区大连站)
- 【HDU 5971 Wrestling Match】+ 2016ACM/ICPC亚洲区大连站-重现赛(感谢大连海事大学) + 二分图染色
- 【HDU 5980 Find Small A】+ 2016ACM/ICPC亚洲区大连站-重现赛(感谢大连海事大学)
- HDU 5979 Convex【计算几何】 (2016ACM/ICPC亚洲区大连站)
- HDU 5976 Detachment 【贪心】 (2016ACM/ICPC亚洲区大连站)
- HDU 5976 Detachment 【贪心】 (2016ACM/ICPC亚洲区大连站)
- HDU 5974 A Simple Math Problem(2016ACM/ICPC亚洲区大连站-重现赛 D题)
- HDU-5971 Wrestling Match (2016ACM/ICPC亚洲区大连站)
- hdu 5975 树状数组原理题(16亚洲区域赛大连站)
- 2016年ACM/ICPC 亚洲区域赛 大连站 1011 Weak Pair(现HDU 5877) 树状数组离散化+dfs
- HDU 5952 Counting Cliques(2016ACM/ICPC亚洲区沈阳站-重现赛)
- hdu5971 Wrestling Match(染色法判二分) 2016ACM/ICPC亚洲区大连站
- HDU 5948 Thickest Burger 【模拟】 (2016ACM/ICPC亚洲区沈阳站)
- HDU 5952 Counting Cliques 【DFS+剪枝】 (2016ACM/ICPC亚洲区沈阳站)
- HDU 5975 && 2016ICPC大连 E: Aninteresting game(树状数组原理)
- HDU 5954 Do not pour out 积分 二分 — 2016ACM-ICPC亚洲区沈阳站
- HDU 5949 Relative atomic mass 【模拟】 (2016ACM/ICPC亚洲区沈阳站)
- HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)