sicily 1686 Happy Children‘s Day

本文介绍了一种使用线段树的数据结构实现方法,通过具体的代码示例详细解释了线段树的构建、插入及查找操作过程。适用于需要高效区间查询与更新的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线段树,第一次用。。。参考代码写

#include<iostream>

#include<cstdio>
#include<cstring>
using namespace std;
int max(int a,int b){
return a<b?b:a;
}
struct node{
int left;
int right;
int most;
int rest;
int index;
}seg[200010];
int w[100010];
void build(int p,int x,int y){
seg[p].left = x;
seg[p].right = y;
seg[p].rest = 0;
seg[p].most = 0;
seg[p].index = x;
if(y-x>=1){
int mid = (x+y)/2;
build(2*p,x,mid);
build(2*p+1,mid+1,y);
}
}
void insert(int p,int x,int y,int v){
if(x<=seg[p].left && y>=seg[p].right){
seg[p].rest+=v;
seg[p].most+=v;
return ;
}
int rest = seg[p].rest;
seg[p].rest = 0;
seg[2*p].rest+=rest;
seg[2*p].most+=rest;
seg[2*p+1].rest+=rest;
seg[2*p+1].most+=rest;
int mid = (seg[p].left+seg[p].right)/2;
if(x<=mid)insert(2*p,x,y,v);
if(y>mid)insert(2*p+1,x,y,v);
if(seg[2*p].most>=seg[2*p+1].most){
seg[p].most = seg[2*p].most;
seg[p].index = seg[2*p].index;
}else {
seg[p].most = seg[2*p+1].most;
seg[p].index = seg[2*p+1].index;
}
}
int find(int p,int x,int y,int &index){
if(x<=seg[p].left && y>=seg[p].right){
index = seg[p].index;
return seg[p].most;
}
int mid = (seg[p].left+seg[p].right)/2;
int rest = seg[p].rest;
seg[p].rest = 0;
seg[2*p].rest+=rest;
seg[2*p].most+=rest;
seg[2*p+1].rest+=rest;
seg[2*p+1].most+=rest;
if(x<=mid){
if(y>=mid+1){
int index1,index2;
int ans1 = find(2*p,x,y,index1);
int ans2 = find(2*p+1,x,y,index2);
if(ans1>=ans2){
index = index1;
}else {
ans1 = ans2;
index = index2;
}
return ans1;
}else {
int index1;
int ans;
ans = find(2*p,x,y,index1);
index = index1;
return ans;
}
}else{
int index1;
int ans = find(2*p+1,x,y,index1);
index = index1;
return ans;
}
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m),n!=0 && m!=0){
for(int i = 1;i<=n;i++)scanf("%d",&w[i]);
build(1,1,n);
int x,y,z;
char str[10];
for(int i = 1;i<=m;i++){
scanf("%s",str);
if(str[0]=='I'){
scanf("%d%d%d",&x,&y,&z);
insert(1,x,y,z);
}else {
scanf("%d%d",&x,&y);
int ans = find(1,x,y,z);
printf("%d\n",ans);
insert(1,z,z,-ans);
}
}
}
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值