hdu1166题解

来源:互联网 发布:优化机构设置 编辑:程序博客网 时间:2024/05/29 08:10

这道入门题十分经典,基本给出线段树的模板了(建树,改变树,取值)
很容易看出这道题区间维护的是和。

#include <stdio.h>#include <string.h>int tree[150001],N,res[40000];void build(int tn,int left,int right){    int mid;    if(left==right) {   scanf("%d",tree+tn);return;}    mid=(left+right)>>1;    build(tn<<1,left,mid);    build(tn<<1|1,mid+1,right);    tree[tn]=tree[tn<<1]+tree[tn<<1|1];}void chang(int tn,int left,int right,int x,int num){    int mid;    if(left==right) {tree[tn]+=num;return;  }    mid=(left+right)>>1;    if(x<=mid) chang(tn<<1,left,mid,x,num);    else chang(tn<<1|1,mid+1,right,x,num);    tree[tn]=tree[tn<<1]+tree[tn<<1|1];//必须更新父节点}int find(int tn,int left,int right,int x,int y){    int mid;    if(x<=left&&y>=right) return tree[tn];    mid=(left+right)>>1;    if(y<=mid) return find(tn<<1,left,mid,x,y);    else if(x>mid) return find(tn<<1|1,mid+1,right,x,y);    else return find(tn<<1,left,mid,x,y)+find(tn<<1|1,mid+1,right,x,y);}int main(int argc, char const *argv[]){    int i=0,j,T,a,b,k;    char str[10];    scanf("%d",&T);    while(T--){   printf("Case %d:\n",++i );    k=0;    memset(tree,0,150001*sizeof(int));    scanf("%d",&N);    build(1,1,N);    while(scanf("%s",str)!=EOF&&strcmp(str,"End"))    {        scanf("%d %d",&a,&b);        if(strcmp(str,"Add")==0)            chang(1,1,N,a,b);        else if(strcmp(str,"Sub")==0)            chang(1,1,N,a,-b);        else res[k++]=find(1,1,N,a,b);    }    for(j=0;j<k;j++)        printf("%d\n",res[j] );}    return 0;}
0 0
原创粉丝点击