UVA1406 - A Sequence of Numbers(树状数组)
2014-10-28 18:43
281 查看
UVA1406 - A Sequence of Numbers(树状数组)
题目链接
题目大意:
给定N个数字,给两种操作:C x: 把这N个数字都加上x。Q x:查询这N个数里面有多少个数字和2^x取且大于0.最后把每个查询的结果求和作为答案。
解题思路:
查询与2^x取且为1,那么就意味这那个符合要求的数的第x位要是1。
但是这里还有全部加上x的操作,可以用一个变量来记录所有C操作的x的和。有这个加数的话,第x位为1的可能可以通过低位进位得到,所以这里开16个树状数组,第i个树状数组存放的是每个数从低位开始,连续的i位的值。例如7:第0个树状数组就加上1, 第1个树状数组就加上3, 第2个树状数组就加上7...
接下来要分情况讨论:首先如果加数是1XXX 那么 1) 1xxx + 0xxx = 1xxx这是符合条件的,而1xxx的范围【1000,1111】 。 2) 1xxx + 1xxx = 11xxx 这是符合条件的,11xxx的范围【11000,11111】。其次如果是 0xxx,也是分两种情况考虑,同理得到范围【1000,1111】.得到了最后符合条件的数,通过减去已知的加数,就可以求出符合查询要求的范围。在通过树状数组统计一下这个范围内的数有多少个存在。
注意:判断某个位是否位1要用&,不要单纯的判断大小。还有每个加数在对应每次查询的时候记得要取模上2^(x + 1).因为只有后面的x位是需要用的。
代码:
题目链接
题目大意:
给定N个数字,给两种操作:C x: 把这N个数字都加上x。Q x:查询这N个数里面有多少个数字和2^x取且大于0.最后把每个查询的结果求和作为答案。
解题思路:
查询与2^x取且为1,那么就意味这那个符合要求的数的第x位要是1。
但是这里还有全部加上x的操作,可以用一个变量来记录所有C操作的x的和。有这个加数的话,第x位为1的可能可以通过低位进位得到,所以这里开16个树状数组,第i个树状数组存放的是每个数从低位开始,连续的i位的值。例如7:第0个树状数组就加上1, 第1个树状数组就加上3, 第2个树状数组就加上7...
接下来要分情况讨论:首先如果加数是1XXX 那么 1) 1xxx + 0xxx = 1xxx这是符合条件的,而1xxx的范围【1000,1111】 。 2) 1xxx + 1xxx = 11xxx 这是符合条件的,11xxx的范围【11000,11111】。其次如果是 0xxx,也是分两种情况考虑,同理得到范围【1000,1111】.得到了最后符合条件的数,通过减去已知的加数,就可以求出符合查询要求的范围。在通过树状数组统计一下这个范围内的数有多少个存在。
注意:判断某个位是否位1要用&,不要单纯的判断大小。还有每个加数在对应每次查询的时候记得要取模上2^(x + 1).因为只有后面的x位是需要用的。
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int M = 7e4; const int N = 20; #define lowbit(x) ((x)&(-x)) typedef long long ll; int n; int t , C [M]; void add (int k, int x, int v) { while (x < M) { C[k][x] += v; x += lowbit(x); } } ll sum (int k, int x) { int ret = 0; while(x > 0) { ret += C[k][x]; x -= lowbit(x); } return ret; } void init () { t[0] = 1; for (int i = 1; i < N; i++) t[i] = t[i - 1] * 2; } void handle (int num) { for (int i = N - 1; i >= 0; i--) { add(i, num + 1, 1); if (num >= t[i]) num -= t[i]; } } ll solve () { ll ans = 0; int addnum = 0; char str[10]; int x, l, r; while (scanf ("%s", str) && str[0] != 'E') { scanf ("%d", &x); if (str[0] == 'C') addnum = (addnum + x) % t[16]; else { if (addnum & t[x]) { l = t[x + 1] + t[x] - addnum % t[x + 1]; r = min(t[x + 2] - 1 - addnum % t[x + 1], t[16] - 1); ans += sum (x, r + 1) - sum (x, l); } l = t[x] - addnum % t[x + 1]; r = t[x + 1] - 1 - addnum % t[x + 1]; ans += sum (x, r + 1) - sum (x, l); // printf("%d %d %lld\n", min, max, ans); } } return ans; } int main () { init(); int cas = 0, num; while (scanf ("%d", &n) && n != -1) { memset (C, 0, sizeof (C)); for (int i = 0; i < n; i++) { scanf ("%d", &num); handle(num); } printf ("Case %d: %lld\n", ++cas, solve()); } return 0; }
相关文章推荐
- uva 1406 - A Sequence of Numbers(树状数组)
- UVA 1406 - A Sequence of Numbers(树状数组)
- UVA1406 - A Sequence of Numbers(树状数组)
- 树状数组 + 位运算 LA 4013 A Sequence of Numbers
- uva1406 - A Sequence of Numbers 树状数组
- [LeetCode 315] Count of Smaller Numbers After Self (树状数组 Binary Indexed Tree)
- 数组空间Given a sequence of numbers (or array).Find the maximum distance between all the same numbers.
- LeetCode 315 Count of Smaller Numbers After Self(树状数组)
- 题目58:A sequence of numbers
- HDU 2817 A sequence of numbers(数列,简单题)
- 题目58:A sequence of numbers
- UVa 1513 / UVALive 5902 Movie collection (树状数组)
- uva 1428 - Ping pong(树状数组,4级)
- uva 1428 - Ping pong(树状数组,4级)
- UVa:1428 Ping pong (树状数组)
- uva 1428 - Ping pong (树状数组的应用)
- 题目1442:A sequence of numbers
- Beijing 2008 / UVa 1428 / POJ 3928 / HDU 2492 Ping pong (树状数组)
- A Sequence of Numbers HDU
- HDU 2817 A sequence of numbers