HDU 1166 敌兵布阵 (我的树状数组加线段树点修改模板)
来源:互联网 发布:淘宝小铺名称能改吗 编辑:程序博客网 时间:2024/06/11 09:21
思路:本题因为是点修改,所以我们可以用线段树或者是树状数组了。线段树的基本操作我在我的代码中会具体体现,关键是要理解下面这幅图,具体的思想大家可以去看看其他的资料
线段树AC代码:
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;#define N 50005int num[N];struct p{ int l,r,sum;}tree[4*N];void build(int root,int l,int r) //root为当前所在节点的编号,l为它的左边界,r为它的右边界{ tree[root].l=l; tree[root].r=r; if(tree[root].l==tree[root].r) //说明是叶子节点 { tree[root].sum=num[l]; return ; } int mid=(l+r)/2; //区间划分 build(root<<1,l,mid); //左儿子 build(root<<1|1,1+mid,r); //右儿子 tree[root].sum=tree[root<<1 ].sum+tree[root<<1|1].sum; //当前节点值为两儿子之和}void update(int root,int pos,int val) //因为要更新,所以我们要在根根节点root开始往下找{//pos为当前位置,val为需要更新成的值 if(tree[root].l==tree[root].r) { tree[root].sum=val;//找到了需要跟新的位置,更新它 return ; } int mid=(tree[root].l+tree[root].r)/2; if(pos<=mid) //左儿子 update(root<<1,pos,val); else update(root<<1|1,pos,val); //右儿子 tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;}int query(int root,int L,int R) //root 表示根节点,[L,R]表示要查询的区间{ if(L<=tree[root].l&&R>=tree[root].r) return tree[root].sum; // [L,R]要查询的区间包含root 节点表示的区间直接返回root 节点的sum 值 int mid=(tree[root].l+tree[root].r)/2,ret=0; if(L<=mid)ret+=query(root<<1,L,R); if(R>mid)ret+=query(root<<1|1,L,R); return ret;}int main(){ int t,j,n,a,b,i; char str[10]; scanf("%d",&t); for(j=1;j<=t;j++) { scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&num[i]); build(1,1,n); printf("Case %d:\n",j); while(1) { scanf("%s",str); if(strcmp(str,"End")==0) break; scanf("%d %d",&a,&b); if(str[0]=='Q') { if(a>b)swap(a,b); printf("%d\n",query(1,a,b)); } else if(str[0]=='A') { num[a]=num[a]+b; update(1,a,num[a]); } else if(str[0]=='S') { num[a]=num[a]-b; update(1,a,num[a]); } } } return 0;}
树状数组:
#include<string.h>#include<stdio.h>#include<math.h>int a[50005];int n;typedef __int64 ll;int lowbit(int t){ return t&(-t);//如果某个结点是左子节点,那么它的父节点的编号为i+lowbit(i)} //右子节点的父节点编号为i-lowbit(i)void insert(int t,int d){ while(t<=n) //插入操作 { a[t]+=d; t=t+lowbit(t); }}ll getsum(int t){ ll sum=0; while(t>0) { sum+=a[t]; t=t-lowbit(t); } return sum;}int main(){ int T,i,j,k,t; scanf("%d",&T); for(t=1;t<=T;t++) { memset(a,0,sizeof(a)); scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&k); insert(i,k); } // getchar(); char str[10]; scanf("%s",str); printf("Case %d:\n",t); while(strcmp(str,"End")!=0) { int x,y; scanf("%d %d",&x,&y); if(strcmp(str,"Query")==0) printf("%I64d\n",getsum(y)-getsum(x-1)); else if(strcmp(str,"Add")==0) insert(x,y); else if(strcmp(str,"Sub")==0) insert(x,(-1)*y); //getchar(); scanf("%s",str); } } return 0;}
0 0
- HDU 1166 敌兵布阵 (我的树状数组加线段树点修改模板)
- HDU 1166 敌兵布阵 【简单的树状数组||线段树】
- HDU 1166 敌兵布阵(树状数组,线段树)
- hdu 1166敌兵布阵(树状数组or线段树)
- hdu 1166 敌兵布阵(树状数组 | 线段树)
- hdu 1166 敌兵布阵(线段树OR树状数组)
- hdu 1166 敌兵布阵(树状数组 or 线段树)
- HDU-#1166 敌兵布阵 (树状数组&线段树)
- HDU 1166 敌兵布阵 (线段树 & 树状数组)
- HDU - 1166 - 敌兵布阵 (树状数组 or 线段树)
- hdu-1166 敌兵布阵 (线段树或树状数组)
- 【HDU】-1166-敌兵布阵(树状数组,线段树)
- HDU 1166 敌兵布阵 ( 树状数组,线段树)
- hdu 1166 敌兵布阵(线段树,树状数组)
- HDU 1166 敌兵布阵(线段树,树状数组)
- hdu 1166 敌兵布阵 (线段树、树状数组模板,单点更新)
- HDU 1166 敌兵布阵(树状数组 or 线段树 单点修改 区间求和)
- HDU 1166 敌兵布阵(树状数组模板)
- 判断数据库向DataTable填充之后字段是否是空值
- POJ-3684 Labeling Balls
- hdoj.2077 汉诺塔IV 20140808
- 表达式求值
- spring 官方下载地址(Spring Framework 3.2.x&Spring Framework 4.0.x)
- HDU 1166 敌兵布阵 (我的树状数组加线段树点修改模板)
- 函数名与函数指针
- HDU 3374 KMP 最大表示法 最小表示法
- ibatis 学习
- >>> FilterDispatcher <<< is deprecated! Please use the new filters!
- 你的收派件范围被固定了吗
- SpringMVC2.5.X支持JSON
- 最短路径
- makefile 中 $@ $^ %< 使用