博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线段树 单点修改+区间修改和查询 例题+代码
阅读量:3898 次
发布时间:2019-05-23

本文共 3443 字,大约阅读时间需要 11 分钟。

目录


【单点修改,区间查询 例题】

1.单点修改、区间查询 - hdu 1166 敌兵布阵

2.单点修改、区间查询最值 - hdu 1754 I Hate It

【hdu 1166 敌兵布阵】

【代码】

const int maxn=50000;int n,a[maxn+10];int sum[4*maxn+10];void build(int k,int l,int r){    if(l==r)    {        sum[k]=a[l];        return;    }    int mid=l+r>>1;    build(k<<1,l,mid);    build(k<<1|1,mid+1,r);    sum[k]=sum[k<<1]+sum[k<<1|1];}void change(int k,int l,int r,int x,int v){    if(r
x) return; if(l==r&&l==x) { sum[k]+=v; return; } int mid=l+r>>1; change(k<<1,l,mid,x,v); change(k<<1|1,mid+1,r,x,v); sum[k]=sum[k<<1]+sum[k<<1|1];}int query(int k,int l,int r,int x,int y){ if(y
r) return 0; if(l>=x&&r<=y) return sum[k]; int mid=l+r>>1; int res; res=query(k<<1,l,mid,x,y); res+=query(k<<1|1,mid+1,r,x,y); return res;}int main(){ int t; scanf("%d",&t); for(int _=1;_<=t;_++) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); printf("Case %d:\n",_); char s[10]; while(~scanf("%s",s)) { int x,y; if(s[0]=='E') break; scanf("%d%d",&x,&y); if(s[0]=='A') change(1,1,n,x,y); else if(s[0]=='S') change(1,1,n,x,-y); else printf("%d\n",query(1,1,n,x,y)); } } return 0;}

【hdu 1754 I Hate It 】

线段树单点修改区间查询最值模板题。

【代码】

const int maxn=200000;int n,a[maxn+10];int ma[4*maxn+10];void build(int k,int l,int r){    if(l==r)    {        ma[k]=a[l];        return;    }    int mid=l+r>>1;    build(k<<1,l,mid);    build(k<<1|1,mid+1,r);    ma[k]=max(ma[k<<1],ma[k<<1|1]);}void change(int k,int l,int r,int x,int v){    if(r
x) return; if(l==r&&l==x) { ma[k]=v; return; } int mid=l+r>>1; change(k<<1,l,mid,x,v); change(k<<1|1,mid+1,r,x,v); ma[k]=max(ma[k<<1],ma[k<<1|1]);}int query(int k,int l,int r,int x,int y){ if(y
r) return 0; if(l>=x&&r<=y) return ma[k]; int mid=l+r>>1; int res; res=max(query(k<<1,l,mid,x,y),query(k<<1|1,mid+1,r,x,y)); return res;}int main(){ int n,m; while(~scanf("%d%d",&n,&m)) { for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); while(m--) { char c; int x,y; scanf(" %c%d%d",&c,&x,&y); if(c=='U') change(1,1,n,x,y); else printf("%d\n",query(1,1,n,x,y)); } } return 0;}

【区间修改,区间查询 例题】

【hdu 1698 Just a Hook】

区间修改、区间查询区间和

【标记下传】

const int maxn=100000;int n,a[maxn+10];int add[4*maxn+10],sum[4*maxn+10];void build(int k,int l,int r){    if(l==r)    {        sum[k]=1;        return;    }    int mid=l+r>>1;    build(k<<1,l,mid);    build(k<<1|1,mid+1,r);    sum[k]=sum[k<<1]+sum[k<<1|1];}void Add(int k,int l,int r,int v)        //把区间[l,r]所有数变成v{    add[k]=v;          //打标记    sum[k]=(r-l+1)*v;  //维护区间和    return;}void pushdown(int k,int l,int r,int mid) //标记下传{    if(add[k]==0) return;         //没有标记则不用考虑    Add(k<<1,l,mid,add[k]);       //下传到左子树    Add(k<<1|1,mid+1,r,add[k]);   //下传到右子树    add[k]=0;                     //清零}void modify(int k,int l,int r,int x,int y,int v)  //给定区间[x,y]所有数变成v{    if(l>=x&&r<=y) return Add(k,l,r,v);    int mid=l+r>>1;    pushdown(k,l,r,mid);          //到达每一个结点都要下传标记    if(x<=mid) modify(k<<1,l,mid,x,y,v);    if(mid
=x&&r<=y) return sum[k]; int mid=l+r>>1,res=0; pushdown(k,l,r,mid); //下传标记 if(x<=mid) res+=query(k<<1,l,mid,x,y); if(mid

【~~】

转载地址:http://oyben.baihongyu.com/

你可能感兴趣的文章
用C#通过888-TT打印中文标签
查看>>
sendmail 出现 My unqualified host name的解决办法
查看>>
彻底解决lazarus安装组件后烦人的编译时单元找不到的问题!
查看>>
Delphi的参数修饰const/var/output 与C++的对应关系
查看>>
C++ free与delete区别
查看>>
VC的字符串转换atlconv的使用
查看>>
Twitter的分布式自增ID算法snowflake (Java版)
查看>>
CentOS7 安装配置FastDFS
查看>>
递归算法的时间复杂度
查看>>
数据结构之图(存储结构、遍历)
查看>>
使用sizeof计算类的大小
查看>>
乐观锁与悲观锁——解决并发问题
查看>>
operator 类型转换及重载
查看>>
HTTP状态码
查看>>
TCP/IP详解--举例明白发送/接收缓冲区、滑动窗口协议之间的关系
查看>>
TCP/IP详解--再次深入理解TCP网络编程中的send和recv
查看>>
TCP与UDP收发的时候TCP有缓冲区还是UDP有缓冲区,使用它们时该注意什么?
查看>>
C++中map、hash_map、unordered_map、unordered_set通俗辨析
查看>>
clone的fork与pthread_create创建线程有何不同&pthread多线程编程的学习小结
查看>>
运算符重载参数的顺序对运算是否有影响
查看>>