[CF-EDU]Segment Tree, part 1 » Step 2 » Practice
创始人
2025-05-28 13:37:29
0

A

Segment with the Maximum Sum

题意:给定长度为n的数组,查询最大子段和。每次操作将下标为i的改成v

思路:线段树维护sum,lmax,rmax,tmax:区间和,区间最大前缀和,区间最大后缀和,区间最大子段和。

如何维护父节点的区间最大前缀和:

(1)左儿子的最大前缀和

(2)左儿子的区间和+右儿子的最大前缀和

如何维护父节点的区间最大后缀和:

(1)右儿子的最大后缀和

(2)右儿子的区间和+左儿子的最大前缀和

如何维护父节点最大子段和:

(1)左儿子的最大子段和

(2)右儿子的最大子段和

(3)左儿子的最大后缀和+右儿子的最大前缀和

#include 
#define ios cin.sync_with_stdio(false)
#define PII pair
#define int long long
typedef long long ll;
const int N=1e5+10;
const int inf=0x3f3f3f3f;using namespace std;
int n,m;
int a[N];
struct node{int l,r;ll sum;ll lmax,rmax,tmax;
}tr[N*4];
void pushup(int u)
{node &root=tr[u],&l=tr[u<<1],&r=tr[u<<1|1];root.sum=l.sum+r.sum;root.lmax=max(l.lmax,l.sum+r.lmax);root.rmax=max(r.rmax,r.sum+l.rmax);root.tmax=max({l.tmax,r.tmax,l.rmax+r.lmax});
}
void build(int u,int l,int r)
{if(l==r) tr[u]={l,r,a[l],a[l],a[l],a[l]};else {tr[u]={l,r};int mid=l+r>>1;build(u<<1,l,mid);build(u<<1|1,mid+1,r);pushup(u);}
}
int query(int u,int l,int r)
{if(tr[u].l>=l&&tr[u].r<=r) return tr[u].tmax;else{int mid=tr[u].l+tr[u].r>>1;int ans=0;if(l<=mid) ans=max(ans,query(u<<1,l,r));if(r>=mid+1) ans=max(ans,query(u<<1|1,l,r));return ans;}
}
void modify(int u,int x,int v)
{if(tr[u].l==x&&tr[u].r==x) tr[u]={x,x,v,v,v,v};else{int mid=tr[u].l+tr[u].r>>1;if(x<=mid) modify(u<<1,x,v);else modify(u<<1|1,x,v);pushup(u);}
}
void solve()
{cin>>n>>m;for(int i=0;i>a[i];build(1,0,n-1);cout<>x>>v;modify(1,x,v);cout<>_t;while(_t--) solve();system("pause");return 0;
}

B

K-th one

题意:给定长度为n的数组,数组元素只能取值0或1。m次操作,

操作1:下标为i的元素取反

操作2:查询第k个1的位置(注意:1个数从0开始编号)

思路:线段树存储区间和。查询时,若左儿子的区间和>=k,那么递归查询左儿子;否则递归查询右儿子,在递归时需要让k减去左儿子的区间和。

#include 
#define ios cin.sync_with_stdio(false)
#define PII pair
typedef long long ll;
const int N=1e5+10;
const int inf=0x3f3f3f3f;using namespace std;
int n,m;
int a[N];
struct node{int l,r;int sum;
}tr[N*4];
void pushup(int u)
{tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;
}
void build(int u,int l,int r)
{if(l==r) tr[u]={l,r,a[l]};else{tr[u]={l,r};int mid=l+r>>1;build(u<<1,l,mid);build(u<<1|1,mid+1,r);pushup(u);}
}
void modify(int u,int x)
{if(tr[u].l==tr[u].r) tr[u].sum^=1;else{int mid=tr[u].l+tr[u].r>>1;if(x<=mid) modify(u<<1,x);else modify(u<<1|1,x);pushup(u);}
}
int query(int u,int x)
{if(tr[u].l==tr[u].r) return tr[u].l;else{int mid=tr[u].l+tr[u].r>>1;if(tr[u<<1].sum>=x) return query(u<<1,x);else return query(u<<1|1,x-tr[u<<1].sum);}
}
void solve()
{cin>>n>>m;for(int i=0;i>a[i];build(1,0,n-1);while(m--){int op,x;cin>>op>>x;if(op==1) modify(1,x);else cout<>_t;while(_t--) solve();system("pause");return 0;
}

C

First element at least X

题意:给定长度为n的数组,m次操作,

操作1:下标为i的元素改成v

操作2:查询第1个大于等于x的位置(注意:从0开始编号),不存在输出-1.

思路:线段树存储区间最大值。查询时,若左儿子的区间最大值>=x,那么递归查询左儿子;否则递归查询右儿子。叶子节点判断是否大于等于x,不满足返回-1

#include 
#define ios cin.sync_with_stdio(false)
#define PII pair
typedef long long ll;
const int N=1e5+10;
const int inf=0x3f3f3f3f;using namespace std;
int n,m;
int a[N];
struct node{int l,r;int ma;
}tr[N*4];
void pushup(int u)
{tr[u].ma=max(tr[u<<1].ma,tr[u<<1|1].ma);
}
void build(int u,int l,int r)
{if(l==r) tr[u]={l,r,a[l]};else{tr[u]={l,r};int mid=l+r>>1;build(u<<1,l,mid);build(u<<1|1,mid+1,r);pushup(u);}
}
void modify(int u,int x,int v)
{if(tr[u].l==tr[u].r) tr[u].ma=v;else{int mid=tr[u].l+tr[u].r>>1;if(x<=mid) modify(u<<1,x,v);else modify(u<<1|1,x,v);pushup(u);}
}
int query(int u,int x)
{if(tr[u].l==tr[u].r) {if(tr[u].ma>=x) return tr[u].l;else return -1;}else{int mid=tr[u].l+tr[u].r>>1;if(tr[u<<1].ma>=x) return query(u<<1,x);else return query(u<<1|1,x);}
}
void solve()
{cin>>n>>m;for(int i=0;i>a[i];build(1,0,n-1);while(m--){int op;cin>>op;if(op==1){int x,v;cin>>x>>v;modify(1,x,v);}else {int x;cin>>x;cout<>_t;while(_t--) solve();system("pause");return 0;
}

D

First element at least X - 2

题意:给定长度为n的数组,m次操作,

操作1:下标为i的元素改成v

操作2:给定x和l,查询下标j,满足j>=l && a[j]>=x,不存在输出-1.

思路:线段树存储区间最大值。查询时,若左儿子的区间最大值>=x && mid>=l,那么递归查询左儿子;否则或者左儿子无解时 ,递归查询右儿子。叶子节点判断是否大于等于x,下标是否大于等于l,不满足返回-1

#include 
#define ios cin.sync_with_stdio(false)
#define PII pair
typedef long long ll;
const int N=1e5+10;
const int inf=0x3f3f3f3f;using namespace std;
int n,m;
int a[N];
struct node{int l,r;int ma;
}tr[N*4];
void pushup(int u)
{tr[u].ma=max(tr[u<<1].ma,tr[u<<1|1].ma);
}
void build(int u,int l,int r)
{if(l==r) tr[u]={l,r,a[l]};else{tr[u]={l,r};int mid=l+r>>1;build(u<<1,l,mid);build(u<<1|1,mid+1,r);pushup(u);}
}
void modify(int u,int x,int v)
{if(tr[u].l==tr[u].r) tr[u].ma=v;else{int mid=tr[u].l+tr[u].r>>1;if(x<=mid) modify(u<<1,x,v);else modify(u<<1|1,x,v);pushup(u);}
}
int query(int u,int x,int l)
{if(tr[u].l==tr[u].r) {if(tr[u].ma>=x&&tr[u].l>=l) return tr[u].l;else return -1;}else{int mid=tr[u].l+tr[u].r>>1;int ans=-1;if(tr[u<<1].ma>=x&&mid>=l) ans=query(u<<1,x,l);if(ans==-1) ans=query(u<<1|1,x,l);return ans;}
}
void solve()
{cin>>n>>m;for(int i=0;i>a[i];build(1,0,n-1);while(m--){int op;cin>>op;if(op==1){int x,v;cin>>x>>v;modify(1,x,v);}else {int x,l;cin>>x>>l;cout<>_t;while(_t--) solve();system("pause");return 0;
}

相关内容

热门资讯

个人简历中技能特长怎么写 个人简历中技能特长怎么写  技能特长属于具体性描述,它需要全面、详细、有重点地将自身的技能、特长等核...
应届毕业生简历模板word格... 每一届大四学生都必须经历实习之旅才能正式毕业,只是,即将踏入社会的大四学生总纠结于实习简历表格要怎么...
面试特长爱好怎么写 很多简历模板中,都会要求求职者填写“爱好与特长”,其实用人单位会通过这些信息来判断求职者的个性。“爱...
个人简历中的自我评价范文精华...   简历中总是会有一份自我评价,这份自我评价怎么写呢?CN人才网小编整理20则范文。  自我评价一 ...
测试经理简历 测试经理简历模板  招聘者在对个人简历的审核上就是通过个人简历中你所体现出来的技能,让他们看到你的能...
应聘简历自我介绍 应聘简历自我介绍(精选10篇)  当来到一个陌生的地方时,我们不得不需要向他人介绍自己,自我介绍可以...
杜玉堂的简历 -管理资料 个人概况姓名:杜玉堂 性别:男 籍贯:山东曹县政治面貌:党员 学历:硕士 专业:细胞生物学 毕业院校...
数学教师个人简历(履历表)模... 个人基本资料姓  名出生日期1977-11-07性  别男婚姻状况未婚身  高170厘米体  重68...
简历特长爱好怎么写 简历特长爱好怎么写  简历特长爱好怎么写,往往的情况下面,我们会把简历中的特长和爱好写在同一个板块中...
应届生个人简历 应届生个人简历(精选10篇)  个人简历是求职者给招聘单位发的一份简要介绍。下面是小编收集整理的应届...
个人简历自荐信 个人简历自荐信范文(精选10篇)  导语:在如今这个时代,我们越来越经常使用自荐信,我们在写自荐信的...
新员工入职简历表 新员工入职简历表  时间一晃而过,眼见着,找工作的时间马上到来,让我们一起来学习写简历吧。简历怎么写...
个人简历的自我评价怎么写 个人简历的自我评价怎么写本人性格开朗、稳重、有活力,待人热情、真诚;工作认真负责,积极主动,能吃苦耐...
社区工作者空白个人简历表格下... 该内容已删除或未通过审核,请返回首页浏览其它页面,感谢你的理解,谢谢。
美术教师招聘简历模板免费下载   美术:泛指创作占有一定平面或空间,且具有可视性的艺术,就叫作美术。它的划分有多种,一般地包括四大...
护士个人简历封面 护士个人简历封面  如何撰写自己的简历,让招聘决策者过目不忘并留下深刻印象,从而为你带来面试机会,是...
服装设计师简历 服装设计师简历  求职者要想求职成功必须要能写出一份优秀的个人简历来,要如何写好简历呢?下面公文站小...
最新简历个人评价   个人评价相信大家都接触到,工作过程中自我评价切记长篇大论,以下这篇是小编整理的“最新简历个人评价...
研究生个人简历 研究生个人简历范文  求职简历求职中,个性突出、特征鲜明的求职者容易在竞争中取胜,而简历也需要个性突...
护士求职个人简历表格   CN人才网小编给大家整理的一篇护士求职个人简历表格,一起来看看吧。姓 名:xxxx 性 别: 男...