首页 > 代码库 > UVA 1406 - A Sequence of Numbers(树状数组)
UVA 1406 - A Sequence of Numbers(树状数组)
UVA 1406 - A Sequence of Numbers
题目链接
题意:给定一些数字,每次操作
C x 表示所有数字加上x
Q x 表示答案加上与2x进行且操作不为0的个数
E 结束,并输出答案
思路:树状数组,首先观察,对于每次查询x而言,只有前x位是是有用的,所以可以开16个树状数组,每个数组表示数字对应前x位下的数字,然后就可以搞了,已经现在加过值为sum,可以推出
2x<=sum+num<2x,这样就可以根据sum来推出num的相应区间,利用区间查询进行查找
代码:
#include <cstdio> #include <cstring> #define lowbit(x) (x&(-x)) const int N = 66666; typedef long long ll; int n, bit[16][N], mi[20]; void add(int i, int x, int v) { while (x < N) { bit[i][x] += v; x += lowbit(x); } } int get(int i, int x) { int ans = 0; while (x) { ans += bit[i][x]; x -= lowbit(x); } return ans; } void init() { memset(bit, 0, sizeof(bit)); int num; while (n--) { scanf("%d", &num); for (int i = 1; i <= 16; i++) { add(i - 1, num % mi[i] + 1, 1); } } } ll solve() { char op[2]; int d, sum = 0; ll ans = 0; while (scanf("%s", op)) { if (op[0] == 'E') break; scanf("%d", &d); if (op[0] == 'C') sum = (sum + d) % mi[16]; else { int tmp = sum % mi[d]; if (sum&mi[d]) ans += get(d, mi[d] - tmp) + get(d, mi[d + 1]) - get(d, mi[d + 1] - tmp); else ans += get(d, mi[d + 1] - tmp) - get(d, mi[d] - tmp); } } return ans; } int main() { int cas = 0; mi[0] = 1; for (int i = 1; i <= 16; i++) mi[i] = mi[i - 1] * 2; while (~scanf("%d", &n) && n != -1) { init(); printf("Case %d: %lld\n", ++cas, solve()); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。