首页 > 代码库 > HDU 1166 敌兵布阵 (我的树状数组加线段树点修改模板)
HDU 1166 敌兵布阵 (我的树状数组加线段树点修改模板)
思路:本题因为是点修改,所以我们可以用线段树或者是树状数组了。线段树的基本操作我在我的代码中会具体体现,关键是要理解下面这幅图,具体的思想大家可以去看看其他的资料
线段树AC代码:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; #define N 50005 int 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; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。