递归代码:

#include <string>
#include <cstring>
#include <iostream>
#include <stdio.h>
using namespace std;
const int inf=1e5+7;        //最多的数量。
int sum[inf<<2],add[inf<<2];    //其中的值都为零。
int arr[inf],n;void PushUp(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}       //应该是按照顺序进行的吧。
void BuiltTree(int l,int r,int rt)      //建树。
{if(l==r)        //说明是到达了叶子结点。{sum[rt]=arr[l];return ;}int m=(l+r)>>1;BuiltTree(l,m,rt<<1);BuiltTree(m+1,r,rt<<1|1);PushUp(rt);
}
//点修改,A[L]+=C;
void UpDate(int l,int r,int L,int C,int rt)
{if(l==r){sum[rt]+=C;     //这里。return ;}int m=(l+r)>>1;if(L<=m)UpDate(l,m,L,C,rt<<1);elseUpDate(m+1,r,L,C,rt<<1|1);PushUp(rt);
}
//下推标志。
void PushDown(int l,int r,int rt)
{if(add[rt]){int m=(l+r)>>1;sum[rt<<1]+=(m-l+1)*add[rt];sum[rt<<1|1]+=(r-m)*add[rt];add[rt<<1]+=add[rt];add[rt<<1|1]+=add[rt];add[rt]=0;}
}
//区间修改,A[L到R]+=C;
void UpDate1(int l,int r,int rt,int L,int R,int C)  //有可能有多次修改。所以每到一个结点都要下推标志。
{if(l>=L&&r<=R){sum[rt]+=(r-l+1)*C;add[rt]+=C;return ;}PushDown(l,r,rt);int m=(l+r)>>1;if(L<=m)UpDate1(l,m,rt<<1,L,R,C);if(R>m)UpDate1(m+1,r,rt<<1|1,L,R,C);PushUp(rt);
}
//区间查询。 求arr[L到R]的和。
int DateQuery(int l,int r,int rt,int L,int R)
{if(l>=L&&r<=R){return sum[rt];}PushDown(l,r,rt);int m=(l+r)>>1;int ans=0;      //如果数据过大的话用long long.if(L<=m)ans+=DateQuery(l,m,rt<<1,L,R);if(R>m)ans+=DateQuery(m+1,r,rt<<1|1,L,R);return ans;
}
void display()
{for(int i=1;i<=4*n;i++)printf("%d ",sum[i]);printf("\n");
}int main()
{cout<<"请输入数组的个数"<<endl;cin>>n;cout<<"请输入数据"<<endl;for(int i=1;i<=n;i++){scanf("%d",&arr[i]);}BuiltTree(1,n,1);display();int flag=0;cout<<"是否进行点修改?是,1;否,0"<<endl;cin>>flag;if(flag==1){int C,L;cout<<"请输入要修改的点和数据"<<endl;cin>>L>>C;UpDate(1,n,L,C,1);display();}cout<<"是否进行区间修改,是,1:否,0"<<endl;cin>>flag;if(flag==1){int L,R,C;cout<<"请输入左右区间和数据"<<endl;cin>>L>>R>>C;UpDate1(1,n,1,L,R,C);display();}cout<<"是否进行区间求和,是,1:否,0"<<endl;cin>>flag;if(flag==1){int L,R;cout<<"请输入左右端点"<<endl;cin>>L>>R;cout<<"结果是"<<endl;cout<<DateQuery(1,n,1,L,R)<<endl;}return 0;
}

非递归代码:

#include <iostream>           //线段树。
#include <cstring>
#include <string>
using namespace std;
const int inf=100007;
int Sum[inf<<2];           //初始的应该是零吧。
int Add[inf<<2];
int A[inf];
int n,N;
void Build(int n)          //首先进行创建。
{    N=1;while(N<n+2)N<<=1;  //首先找出N来。     for(int i=1;i<=n;i++)            Sum[i+N]=A[i];     //之后看看两边的还要管吗。      for(int i=N-1;i>0;i--)    {        Sum[i]=Sum[i<<1]+Sum[i<<1|1];        Add[i]=0;          //在这里进行修改吗。       }
}
void Update(int L,int C)           //之后是进行点修改。sum[l]+=C;
{    for(int s=L+N;s;s>>=1)    {        Sum[s]+=C;    }
}
int Query(int L,int R)       //点修改下的区间查询。sum[L R]的和。
{    int ans=0;    for(int s=L+N-1,t=R+N+1;s^t^1;s>>=1,t>>=1)    {        if(~s&1)ans+=Sum[s^1];        if(t&1)ans+=Sum[t^1];    }    return ans;
}
void Update1(int L,int R,int C)   //区间修改Sum[L R]+=C;
{    int s,t,Ln=0,Rn=0,x=1;    for(s=L+N-1,t=R+N+1;s^t^1;s>>=1,t>>=1,x<<=1 )    {        Sum[s]+=Ln*C;        Sum[t]+=Ln*C;       //这里。         if(~s&1)Add[s^1]+=C,Sum[s^1]+=C*x,Ln+=x;         if(t&1) Add[t^1]+=C,Sum[t^1]+=C*x,Rn+=x;    }    for( ;s;s>>=1,t>>=1)    //链接还是巧妙的啊。     {        Sum[s]+=C*Ln;                Sum[t]+=C*Rn;    }
}
int Query1(int L,int R)        //区间修改上的区间查询。sum【L,R】的和。
{    int s,t,Ln=0,Rn=0,x=1;    int ans=0;    for(s=L+N-1,t=R+N+1;s^t^1;s>>=1,t>>=1,x<<=1)    {        if(Add[s])ans+=Add[s]*Ln;        if(Add[t])ans+=Add[t]*Rn;         if(~s&1)ans+=Sum[s^1],Ln+=x;        if( t&1)ans+=Sum[t^1],Rn+=x;    }    for( ;s;s>>=1,t>>=1)                    //其实加不加是无所谓的。              {        /*if( Add[s])*/ans+=Add[s]*Ln;        //这里为何是不加的呢。              /*if( Add[t])*/ans+=Add[t]*Rn;                            }    return ans;
}int main()
{   cout<<"请输入数组的个数"<<endl;     cin>>n;     cout<<"请输入数组中的值"<<endl;     for(int i=1;i<=n;i++)         cin>>A[i];     Build(n);   //初始化。      for(int i=1;i<=2*N-1;i++)              cout<<Sum[i]<<" ";        cout<<endl;    Update(3,1);    for(int i=1;i<=2*N-1;i++)        cout<<Sum[i]<<" ";        cout<<endl;    int ans=Query(2,4);        cout<<ans<<endl;    Update1(2,4,1);    for(int i=1;i<=2*N-1;i++)        cout<<Sum[i]<<" ";        cout<<endl;    int ans1=Query1(1,4);                //最后一个。              cout<<ans1<<endl;  return 0;
} 

hdu1166 敌兵布阵

http://acm.hdu.edu.cn/showproblem.php?pid=1166

简单线段树点修改和区间查询:

代码:

#include <string>
#include <cstring>
#include <iostream>
#include <stdio.h>
using namespace std;
const int inf=1e5+7;        //最多的数量。
int sum[inf<<2],add[inf<<2];    //其中的值都为零。
int arr[inf],n;void PushUp(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}       //应该是按照顺序进行的吧。
void BuiltTree(int l,int r,int rt)      //建树。
{if(l==r)        //说明是到达了叶子结点。{sum[rt]=arr[l];return ;}int m=(l+r)>>1;BuiltTree(l,m,rt<<1);BuiltTree(m+1,r,rt<<1|1);PushUp(rt);
}
//点修改,A[L]+=C;
void UpDate(int l,int r,int L,int C,int rt)
{if(l==r){sum[rt]+=C;     //这里。return ;}int m=(l+r)>>1;if(L<=m)UpDate(l,m,L,C,rt<<1);elseUpDate(m+1,r,L,C,rt<<1|1);PushUp(rt);
}
//下推标志。
void PushDown(int l,int r,int rt)
{if(add[rt]){int m=(l+r)>>1;sum[rt<<1]+=(m-l+1)*add[rt];sum[rt<<1|1]+=(r-m)*add[rt];add[rt<<1]+=add[rt];add[rt<<1|1]+=add[rt];add[rt]=0;}
}
//区间修改,A[L到R]+=C;
void UpDate1(int l,int r,int rt,int L,int R,int C)  //有可能有多次修改。所以每到一个结点都要下推标志。
{if(l>=L&&r<=R){sum[rt]+=(r-l+1)*C;add[rt]+=C;return ;}PushDown(l,r,rt);int m=(l+r)>>1;if(L<=m)UpDate1(l,m,rt<<1,L,R,C);if(R>m)UpDate1(m+1,r,rt<<1|1,L,R,C);PushUp(rt);
}
//区间查询。 求arr[L到R]的和。
int DateQuery(int l,int r,int rt,int L,int R)
{if(l>=L&&r<=R){return sum[rt];}PushDown(l,r,rt);int m=(l+r)>>1;int ans=0;      //如果数据过大的话用long long.if(L<=m)ans+=DateQuery(l,m,rt<<1,L,R);if(R>m)ans+=DateQuery(m+1,r,rt<<1|1,L,R);return ans;
}
void display()
{for(int i=1;i<=4*n;i++)printf("%d ",sum[i]);printf("\n");
}int main()
{int t;scanf("%d",&t);int abc=1;while(t--){printf("Case %d:\n",abc++);scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&arr[i]);BuiltTree(1,n,1);string str;while(1){cin>>str;if(str=="End")break;int a,b;scanf("%d %d",&a,&b);if(str=="Query"){printf("%d\n",DateQuery(1,n,1,a,b));} else if(str=="Add")UpDate(1,n,a,b,1);else{b=-1*b;UpDate(1,n,a,b,1);}   }}return 0;
}

线段树递归和非递归实现+hdu1166 敌兵布阵相关推荐

  1. 线段树版子题【HDU - 1166 敌兵布阵】【HDU-1754 I Hate It】【HDU-1698 Just a Hook】【OpenJ_Bailian3439A Simple Pro】

    敌兵布阵 C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动 ...

  2. HDU1166 敌兵布阵【树状数组】

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  3. HDU1166 敌兵布阵(树状数组模板题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  4. hdu1166敌兵布阵 树状数组裸题

    树状数组裸题 动态更新区间内的点,动态查询区间和 敌兵布阵 ac代码 #include<iostream> #include<algorithm> #include<cs ...

  5. HDU1166 敌兵布阵 单点更新 区间查询

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  6. 小小线段树 以HDU-1166 敌兵布阵为例

    [异世界情绪]日文翻唱<鳥の詩/鸟之诗> 引个流,情绪的鸟之诗真的好听,听着这个学习效率巨高! 文章目录 前言 一.build函数 演示①和②: 二.add函数 演示③: 三.query函 ...

  7. hdu1166敌兵布阵hdu1754I Hate It(线段树入门)

    单点更新是最最基础的线段树,只更新叶子节点,然后把信息用pushup这个函数更新上来. http://acm.hdu.edu.cn/showproblem.php?pid=1166 update单点更 ...

  8. hdu1166 敌兵布阵 线段树

    C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于 ...

  9. hdu-1166敌兵布阵

    这个题目就是考察线段树的基本用法,我自己打了代码,其实就是照模板来的,大概思想已经弄懂了.用c++不能过,说我超时,就改成c的读入读出,这坑爹的过了.我最爱的c++,你肿么了... 这是ac的代码: ...

最新文章

  1. 画出降维后的图片_有没有人能画出《三体》里太阳系被二维化的概念图?
  2. UA MATH571A 检验异方差的非参数回归方法
  3. 中国鱼胶原蛋白行业应用前景与十四五投资建议报告2022年
  4. 双11稳定性负责人叔同讲述:九年双11的云化架构演进和升级
  5. P5020-货币系统【背包】
  6. 三大运营商5G预约用户数近9百万 5G商用进入倒计时
  7. OpenShift 4 - Knative教程(2) 基于Revision/Tag/Traffic实现蓝绿部署和恢复发布
  8. VMware vCenter Server Appliance Photon OS安全修补程序
  9. Vue编写动态组件实践(render函数的使用心得)
  10. redis版本_Redis—重要历史版本
  11. [Swift]LeetCode145. 二叉树的后序遍历 | Binary Tree Postorder Traversal
  12. Java图书管理系统
  13. Pr 视频效果:过渡、透视、通道
  14. eda课程设计,求救!!!!!!!!
  15. 木讷的程序员需要知道的事情 (三)
  16. QQ自由幻想刺客的属性点
  17. stimulsoft mysql_StimulSoft——将炫酷的报表写入你的应用程序
  18. calsite原理_Calcite 处理一条SQL - II (Rels Into Planner)
  19. opencv 图片上画一条线
  20. 代谢组学分析平台都有什么仪器?

热门文章

  1. 排序算法汇总(转载收藏)
  2. 虚拟机ping不通主机,但是主机可以ping通虚拟机(转载)
  3. xcart-子分类/语言不显示
  4. 设计模式原则(单一、开放封闭、里氏代换、依赖倒转、迪米特法则五大原则)...
  5. python中argparse模块
  6. 【网络】解决‘ipconfig不是内部或外部命令,也不是可运行的程序
  7. go flag包获取命令行参数使用示例
  8. Docker多阶段镜像构建Dockerfile脚本示例:构建nodejs前端项目
  9. 服务器上的hdfs的配置文件中,namenode不能设置成127.0.0.1或者localhost,要设置ip或者映射别名
  10. 【網址收藏】解决VSCODE“因为在此系统上禁止运行脚本“报错