线段树 基础单点更新 敌兵布阵
来源:互联网 发布:java分等级并统计个数 编辑:程序博客网 时间:2024/05/22 02:18
题:敌兵布阵
标准线段树模板代码:
#include<cstdio>#include<cstring>const int maxn = 500000 + 10;struct Node{ int left, right, count;}node[maxn];int a[maxn];/**************************************************建树****************************i是区间序号**************l是区间i左边界,r是区间i右边界***从1到n开始建树,直到区间长度为1***即l=r时,结束。count记录区间和**************************************/void maketree(int l, int r, int i){ node[i].left = l; node[i].right = r; if(l == r){ node[i].count = a[l]; return ; } int m = (l + r)/2; maketree(l, m, 2*i); maketree(m + 1, r, 2*i + 1); node[i].count = node[2*i].count + node[2*i + 1].count;}/*********************************************************更新********************i区间序号,x要更新的点。y要更新的值**********flag判断更新方式*****************************************************/void updatetree(int i, int x, int y, int flag){ int l = node[i].left; int r = node[i].right; int m = (l + r)/2; if(r == l){ if(flag) node[i].count += y; else node[i].count -= y; return; } if(x <= m) updatetree(2*i, x, y, flag); else updatetree(2*i + 1, x, y, flag); if(flag) node[i].count += y; else node[i].count -= y; return;}/**************************************************查询****************************************************/int querytree(int l, int r, int i){ int m = (node[i].left + node[i].right)/2; if(node[i].right <= r && node[i].left >= l) return node[i].count; int ans = 0; if(r <= m) return querytree(l, r, 2*i); else if(l > m) return querytree(l, r, 2*i + 1); else return querytree(l, m, 2*i) + querytree(m + 1, r, 2*i + 1);}int main(){ int T, n; char str[20]; scanf("%d", &T); for(int i = 1; i <= T; i++){ printf("Case %d:\n", i); scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); maketree(1, n, 1); int x, y; while(scanf("%s", str)){ if(str[0] == 'E') break; scanf("%d%d", &x, &y); if(str[0] == 'Q') printf("%d\n", querytree(x, y, 1)); else if(str[0] == 'A') updatetree(1, x, y, true); else updatetree(1, x, y, false); } } return 0;}
优美的线段树代码:
#include <cstdio>/*****************************灵活的使用宏定义******************************/#define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1const int maxn = 55555;int sum[maxn<<2];void PushUP(int rt) {sum[rt] = sum[rt<<1] + sum[rt<<1|1];}/***************************************************建树*************** 此处并没有使用结构体,只是记录了区间和sum,但l,r与区间序号紧密关联***********************************/void build(int l,int r,int rt) {if (l == r) {scanf("%d",&sum[rt]);return ;}int m = (l + r) >> 1;build(lson);build(rson);PushUP(rt);}/*************************************** *****************更新***************** 此处没用标记更新方式(加或减),巧妙 地在调用时处理了正负号,减少函数参数***************************************/void update(int p,int add,int l,int r,int rt) {if (l == r) {sum[rt] += add;return ;}int m = (l + r) >> 1;if (p <= m) update(p , add , lson);else update(p , add , rson);PushUP(rt);}/*********************************************************查询****************** 巧妙地引用了变量ret,减少了对m的讨论***************************************/int query(int L,int R,int l,int r,int rt) {if (L <= l && r <= R) {return sum[rt];}int m = (l + r) >> 1;int ret = 0;if (L <= m) ret += query(L , R , lson);if (R > m) ret += query(L , R , rson);return ret;}int main() {int T , n;scanf("%d",&T);for (int cas = 1 ; cas <= T ; cas ++) {printf("Case %d:\n",cas);scanf("%d",&n);build(1 , n , 1);char op[10];while (scanf("%s",op)) {if (op[0] == 'E') break;int a , b;scanf("%d%d",&a,&b);if (op[0] == 'Q') printf("%d\n",query(a , b , 1 , n , 1));else if (op[0] == 'S') update(a , -b , 1 , n , 1);else update(a , b , 1 , n , 1);}}return 0;}
树状数组的代码:
#include<cstdio>#include<cstring>using namespace std;const int maxn = 50000 + 10;int len, a[maxn];char str[50];int lowbit(int x){ return x&(-x);}/******************************更新********************************/void update(int i, int v){ while(i <= len){ a[i] += v; i += lowbit(i); }}/*****************************求和******************************/int sum(int i){ int sum = 0; while(i > 0){ sum += a[i]; i -= lowbit(i); } return sum;}int main(){ int T, v; scanf("%d", &T); for(int i = 1; i <= T; i++){ memset(a, 0, sizeof(a)); scanf("%d", &len); for(int j = 1; j <= len; j++){ scanf("%d", &v); update(j, v); } printf("Case %d:\n", i); while(scanf("%s", str)){ if(str[0] == 'E') break; int x, y; scanf("%d%d", &x, &y); if(str[0] == 'A') update(x, y); else if(str[0] == 'S') update(x, -y); else printf("%d\n", sum(y)-sum(x-1)); } } return 0;}
4 0
- 线段树 基础单点更新 敌兵布阵
- HDU1166敌兵布阵(线段树单点更新)
- HDU1166:敌兵布阵(线段树单点更新)
- hdu1166 敌兵布阵 线段树,单点更新
- HDU1166_敌兵布阵(线段树/单点更新)
- HDU1166_敌兵布阵(线段树/单点更新)
- HDU1166 敌兵布阵 线段树 单点更新
- 敌兵布阵(线段树单点更新)
- hdu1166 敌兵布阵 线段树 单点更新
- Hdu1166 敌兵布阵 线段树、单点更新
- HDU1166:敌兵布阵(线段树 单点更新)
- 敌兵布阵 (线段树 单点更新)
- HDU1166:敌兵布阵(线段树单点更新)
- hdu 1166 敌兵布阵(基础树状数组)(基础线段树--单点更新)
- HDU 1166 敌兵布阵 [线段树-单点更新]
- Hdu-1166 敌兵布阵【线段树(单点更新)】
- 线段树 hdu 1166 敌兵布阵 单点更新区间求和
- 线段树入门[单点更新] 敌兵布阵 HDU 1166
- MySQL初始设置
- 树、二叉树的java实现
- poj 3414 dfs 广度优先搜索
- HDU-#3062 Party(2-SAT)
- 快速排序
- 线段树 基础单点更新 敌兵布阵
- Perfect Cubes
- 线性表、栈和队列、数组和字符串
- Sublime的中文GBK显示乱码的解决方法
- 矩阵构造的一般方法
- android switch语句case expressions must be constant expressions
- java基础之运算符表达式,语句
- 用反射机制简单应用配置文件
- NULL指针、零指针、野指针