HDU1166 敌兵布阵
来源:互联网 发布:唐安琪 知乎 编辑:程序博客网 时间:2024/05/16 05:59
一. 原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166
二. 题目大意:简化为模型为:给一个区间,区间上每个数可看做容器,对容器有增加,减少,查询3种操作。增加减少只针对一个容器,查询可以多个容器连在一起。每次查询输出查询区间共放有多少东西。
三. 解题思路:暴力肯定超时(50000*40000)。线段树,最基础的单点更新。线段树,也就是区间树,树的每个节点代表一个区间,根节点代表最大的区间[0, N],左子树代表[0, mid],右子树代表[mid+1, r],以此类推。每个节点增加一个域代表当前区间共有多少士兵。然后就是线段树基本操作,建立树,单点更新,查询。
四. 代码:
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAX_N = 50010, INF = 0x3f3f3f3f;#define LC(t) t<<1#define RC(t) t<<1|1struct node{ int l, r, cnt;};node seTree[4*MAX_N];void build(int l, int r, int idx){ seTree[idx].l = l; seTree[idx].r = r; seTree[idx].cnt = 0; if(l == r) return; int mid = (l+r)>>1; build(l, mid, LC(idx)); build(mid+1, r, RC(idx));}void add(int idx, int pos, int num){ int l = seTree[idx].l, r = seTree[idx].r; if(l <= pos && r >= pos){ seTree[idx].cnt += num; if(l == r) return; add(LC(idx), pos, num); add(RC(idx), pos, num); }}int query(int l, int r, int idx){ int lSide = seTree[idx].l, rSide = seTree[idx].r; if(lSide == l && rSide == r) return seTree[idx].cnt; int mid = (lSide+rSide)>>1; if(lSide <= l && mid >= r) return query(l, r, LC(idx)); if(mid+1 <= l && rSide >= r) return query(l, r, RC(idx)); if(lSide <= l && rSide >= r){ return query(l, mid, LC(idx)) + query(mid+1, r, RC(idx)); }}int main(){ //freopen("in.txt", "r", stdin); int T, N, i, num, kase = 1; char command[11]; scanf("%d", &T); while(T--){ printf("Case %d:\n", kase++); scanf("%d", &N); build(0, N, 1); for(i = 1; i <= N; i++){ scanf("%d", &num); add(1, i, num); } while(~scanf("%s", command)){ if(command[0] == 'E') break; int a, b; scanf("%d %d", &a, &b); switch(command[0]) { case 'A': add(1, a, b); break; case 'S': add(1, a, -b); break; case 'Q': printf("%d\n", query(a, b, 1)); break; } } } return 0;}
法二:树状数组,由于每个整数都可以表示为2的幂次方的和,所以如果对于当前数son,定义father = son+2^k,其中k为son转化为二进制之后末尾0的个数,这样在整数集上刚好存在一一对应的关系。树的每个节点表示从1到该节点对于的值的和。一个树状数组只能单点更新和求前缀和。
#include <cstdio>#include <cstring>using namespace std;const int MAX_N = 50500;const int INF = 0x3f3f3f3f;int tree[MAX_N], N;int lowbit(int x){ return x & (-x);}void update(int pos, int ele){ while(pos <= N){ tree[pos] += ele; pos += lowbit(pos); }}int query(int pos){ int res = 0; while(pos > 0){ res += tree[pos]; pos -= lowbit(pos); } return res;}int main(){ //freopen("in.txt", "r", stdin); int T, i, ele, a, b, kase = 1; char str[10]; scanf("%d", &T); while(T--){ printf("Case %d:\n", kase++); memset(tree, 0, sizeof(tree)); scanf("%d", &N); for(i = 1; i <= N; i++){ scanf("%d", &ele); update(i, ele); } while(~scanf("%s", str) && str[0]!='E'){ scanf("%d %d", &a, &b); switch(str[0]) { case 'Q': printf("%d\n", query(b)-query(a-1)); break; case 'A': update(a, b); break; case 'S': update(a, -b); break; } } } return 0;}
0 0
- hdu1166 敌兵布阵
- hdu1166 敌兵布阵
- HDU1166 敌兵布阵
- hdu1166 敌兵布阵
- hdu1166 敌兵布阵
- hdu1166(敌兵布阵)
- HDU1166:敌兵布阵
- hdu1166敌兵布阵
- HDU1166--敌兵布阵
- HDU1166 敌兵布阵
- hdu1166 敌兵布阵
- hdu1166 敌兵布阵
- hdu1166敌兵布阵
- hdu1166敌兵布阵
- hdu1166 敌兵布阵
- HDU1166 敌兵布阵
- hdu1166 敌兵布阵
- hdu1166敌兵布阵
- Ubuntu 16.04下安装Tensorflow(GPU)
- C语言中的进制转换 itoa & sprintf
- C#控制台 用继承输出hello world
- C++类构造函数初始化列表
- Build Opus Codec for iOS
- HDU1166 敌兵布阵
- python系列笔记1
- 官方文档之Cookie
- Make管理器及Makefile的tips
- 剑指offer-机器人的运动范围
- 实现一个so库文件名称为listupper.so,so文件中实现一个函数
- 毕业季,大公司?还是创业公司?
- POJ 3069 Saruman's Army(贪心)
- 华为 弹性云服务器 外网访问不了web项目 购买硬盘怎么没有了 解决方法