備戰藍橋杯---線段樹基礎1

引入:RMQ問題:

什么是RMQ?

顯然,我們無法用前綴維護,因此,我們需要用到線段樹的知識:

什么是線段樹?

線段樹是用一種樹狀結構存儲一個連續區間信息的數據結構

下面我們用圖解釋用它來查詢2--5信息的方式:

由此,我們可以得到幾點性質:

1.他是一個平衡的二叉樹。

2.對于任意兩個節點,要么完全包含,要么互不相交。

3.任意的線段[a,b]在查詢過程中最多分為log(b-a)個。

4.除建樹外為logn.

我們來一道模板題試試水:

下面是AC代碼:

#include<bits/stdc++.h>
using namespace std;
int n,a[100000];
int tree[4*100000];
void build(int p,int l,int r){if(l==r){tree[p]=a[l];return;}int mid=(l+r)/2;build(p*2,l,mid);build(p*2+1,mid+1,r);tree[p]=tree[p*2+1]+tree[p*2];return;
}
void change(int p,int l,int r,int pos,int num){if(l==r){tree[p]+=num;return;}int mid=(l+r)/2;if(pos<=mid) change(p*2,l,mid,pos,num);else change(p*2+1,mid+1,r,pos,num);tree[p]=tree[2*p]+tree[2*p+1];return;
}
int calc(int p,int l,int r,int x,int y){if(l>=x&&r<=y){return tree[p];}int mid=(l+r)/2;if(y<=mid) return calc(p*2,l,mid,x,y);if(x>mid) return calc(p*2+1,mid+1,r,x,y);return calc(p*2,l,mid,x,mid)+calc(p*2+1,mid+1,r,mid+1,y);
}
int main(){cin>>n;for(int i=1;i<=n;i++) cin>>a[i];build(1,1,n);for(int i=1;i<=n;i++){int x,y,z;cin>>x>>y>>z;if(x==1){change(1,1,n,y,z);}else cout<<calc(1,1,n,y,z);} 
} 

讓我們來看看它的實際應用吧:

區間和問題之懶標記:

我們維護一下節點的兩個信息:

1.sum[i]第i個節點對應的區間和。

2.add[i]第i個節點對應區間整體加上的值并且沒有同步給兒子。

這里我們就知道了為什么叫lazy,該標記僅當被標記的區間有部分被更改才順路把標記下放給它的兒子。這樣就可以減少修改的次數了。

下面是AC代碼:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,a[100010],m;
int tree[4*100010];
int lazy[4*100010];
void build(int p,int l,int r){//建樹 if(l==r){tree[p]=a[l];return;}int mid=(l+r)/2;build(p*2,l,mid);build(p*2+1,mid+1,r);tree[p]=tree[p*2+1]+tree[p*2];return;
}
void pushdown(int p,int l,int r){//lazy標記下移 int mid=(l+r)/2;lazy[p*2]+=lazy[p];lazy[p*2+1]+=lazy[p];tree[p*2]+=lazy[p]*(mid-l+1);//更新子節點的值 tree[p*2+1]+=lazy[p]*(r-mid);lazy[p]=0;//自己因為下移清0 
}
void change(int p,int l,int r,int x,int y,int num){if(x<=l&&r<=y){tree[p]+=num*(r-l+1);lazy[p]+=num;return;}if(lazy[p]!=0){//區間部分修改,需要下移 pushdown(p,l,r);}int mid=(l+r)/2;if(y<=mid) change(p*2,l,mid,x,y,num);if(x>mid) change(p*2+1,mid+1,r,x,y,num);if(x<=mid&&y>mid){change(p*2,l,mid,x,mid,num);change(p*2+1,mid+1,r,mid+1,y,num);}tree[p]=tree[2*p]+tree[2*p+1];return;
}
int calc(int p,int l,int r,int x,int y){if(l>=x&&r<=y){return tree[p];}if(lazy[p]!=0){pushdown(p,l,r);}int mid=(l+r)/2;if(y<=mid) return calc(p*2,l,mid,x,y);if(x>mid) return calc(p*2+1,mid+1,r,x,y);return calc(p*2,l,mid,x,mid)+calc(p*2+1,mid+1,r,mid+1,y);
}
signed main(){cin>>n>>m;for(int i=1;i<=n;i++) scanf("%lld",&a[i]);build(1,1,n);for(int i=1;i<=m;i++){int x,y,k,op;scanf("%lld%lld%lld",&op,&x,&y);if(op==1){scanf("%lld",&k);change(1,1,n,x,y,k);}else cout<<calc(1,1,n,x,y)<<endl;} 
} 

區間平方和問題:

我們還是用lazy標記,不過這時我們維護的sum應該是平方和。那么我們如何維護呢?

\sum (ai+k)^2=\sum ai^2+2k\sum ai+\sum k^2

因此我們只要維護ai的前綴和即可。

下面是AC代碼:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,a[100010],m,sum[4*100010];
int tree[4*100010];
int lazy[4*100010];
void pushdown(int p,int l,int r);
int calc(int p,int l,int r,int x,int y,int k);
void build(int p,int l,int r){//建樹 if(l==r){tree[p]=a[l]*a[l];sum[p]=a[l];return;}int mid=(l+r)/2;build(p*2,l,mid);build(p*2+1,mid+1,r);tree[p]=tree[p*2+1]+tree[p*2];sum[p]=sum[p*2+1]+sum[p*2+1];return;
}
void pushdown(int p,int l,int r){//lazy標記下移 int mid=(l+r)/2;lazy[p*2]+=lazy[p];lazy[p*2+1]+=lazy[p];tree[p*2]+=2*lazy[p]*(sum[2*p])+lazy[p]*lazy[p]*(mid-l+1);//更新子節點的值 tree[p*2+1]+=2*lazy[p]*(sum[2*p+1])+lazy[p]*lazy[p]*(r-mid);sum[p*2]+=lazy[p]*(mid-l+1);sum[p*2+1]+=lazy[p]*(r-mid);lazy[p]=0;//自己因為下移清0 
}
void change(int p,int l,int r,int x,int y,int num){if(x<=l&&r<=y){tree[p]+=2*num*(sum[p])+num*num*(r-l+1);sum[p]+=num*(r-l+1);lazy[p]+=num;return;}if(lazy[p]!=0){//區間部分修改,需要下移 pushdown(p,l,r);}int mid=(l+r)/2;if(y<=mid) change(p*2,l,mid,x,y,num);if(x>mid) change(p*2+1,mid+1,r,x,y,num);if(x<=mid&&y>mid){change(p*2,l,mid,x,mid,num);change(p*2+1,mid+1,r,mid+1,y,num);}tree[p]=tree[2*p]+tree[2*p+1];sum[p]=sum[2*p]+sum[2*p+1];return;
}
int calc(int p,int l,int r,int x,int y,int k){if(l>=x&&r<=y){if(k==1) return tree[p];else return sum[p];}if(lazy[p]!=0){pushdown(p,l,r);}int mid=(l+r)/2;if(y<=mid) return calc(p*2,l,mid,x,y,k);if(x>mid) return calc(p*2+1,mid+1,r,x,y,k);return calc(p*2,l,mid,x,mid,k)+calc(p*2+1,mid+1,r,mid+1,y,k);
}
signed main(){cin>>n>>m;for(int i=1;i<=n;i++) scanf("%lld",&a[i]);build(1,1,n);for(int i=1;i<=m;i++){int x,y,k,op;scanf("%lld%lld%lld",&op,&x,&y);if(op==1){scanf("%lld",&k);change(1,1,n,x,y,k);}else cout<<calc(1,1,n,x,y,1)<<endl;} 
} 

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711434.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711434.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711434.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++知識點總結(22):模擬算法真題 ★★★★☆《越野比賽》

二、越野比賽 1. 審題 題目描述 最近賽車手 K a l n Kaln Kaln 加入了心心念念的 F a r Far Far 車隊&#xff0c;馬上就迎來了自己的首秀&#xff0c;參加一場直線加速賽&#xff1a;已知 F a r Far Far 車隊會提供 n n n 種類型的賽車&#xff0c; K a l n Kaln Kaln 只…

【數據結構】隊列OJ題《用隊列實現棧》(題庫+解析+代碼)

1.前言 通過前面隊列的實現和詳解大家對隊列應該有一定熟悉了&#xff0c;現在上強度開始做題吧 隊列詳解&#xff1a;http://t.csdnimg.cn/dvTsW 2.OJ題目訓練225. 用隊列實現棧 題目分析 請你僅使用兩個隊列實現一個后入先出&#xff08;LIFO&#xff09;的棧&#xff0…

git 設置代理 取消代理

設置代理 git config --global http.proxy 127.0.0.1:7890 git config --global https.proxy 127.0.0.1:7890注意&#xff1a;加上 --global 是對 git 設置全局代理&#xff0c;不加 --global 對指定倉庫目錄設置代理&#xff0c;局部代理 查看已修改 git 配置信息 git conf…

【GPU驅動開發】- AST簡介

前言 不必害怕未知&#xff0c;無需恐懼犯錯&#xff0c;做一個Creator&#xff01; AST&#xff0c;抽象語法樹&#xff0c;是一種包含豐富語義信息的格式&#xff0c;其中包括類型、表達式樹和符號等。 TranslationUnitDecl&#xff1a;該類表示一個輸入源文件 ASTContext&…

Qt注冊類對象單例與單類型區別

1.實現類型SingletonTypeExample #ifndef SINGLETONTYPEEXAMPLE_H #define SINGLETONTYPEEXAMPLE_H#include <QObject>class SingletonTypeExample : public QObject {Q_OBJECT public://只能顯示構造類對象explicit SingletonTypeExample(QObject *parent nullptr);//…

【學習筆記】深度學習實戰 | LeNet

簡要聲明 學習相關網址 [雙語字幕]吳恩達深度學習deeplearning.aiPapers With CodeDatasets 深度學習網絡基于PyTorch學習架構&#xff0c;代碼測試可跑。本學習筆記單純是為了能對學到的內容有更深入的理解&#xff0c;如果有錯誤的地方&#xff0c;懇請包容和指正。 參考文獻…

KubeEdge 邊緣計算

文章目錄 1.KubeEdge2.KubeEdge 特點3.KubeEdge 組成4.KubeEdge 架構 KubeEdge # KubeEdgehttps://iothub.org.cn/docs/kubeedge/ https://iothub.org.cn/docs/kubeedge/kubeedge-summary/1.KubeEdge KubeEdge 是一個開源的系統&#xff0c;可將本機容器化應用編排和管理擴展…

藍牙耳機和筆記本電腦配對連接上了,播放設備里沒有顯示藍牙耳機這個設備,選不了輸出設備

環境&#xff1a; WIN10 雜牌藍牙耳機6s 問題描述&#xff1a; 藍牙耳機和筆記本電腦配對連接上了&#xff0c;播放設備里沒有顯示藍牙耳機這個設備&#xff0c;選不了輸出設備 解決方案&#xff1a; 1.打開設備和打印機&#xff0c;找到這個設備 2.選中這個設備&#…

Linux下gcc編譯常用命令詳解

在Linux環境下&#xff0c;使用gcc編譯器進行源代碼的編譯是程序員日常工作的一部分。本篇將介紹一些常用的gcc編譯命令&#xff0c;幫助開發者更好地理解和使用這些命令。 1. 基本編譯命令 gcc工作流程&#xff1a; 編譯單個源文件 gcc source.c -o output這個命令將sour…

20240229筆記

瀏覽器預加載器 手動&#xff1a;prefetch preload <link rel"prefetch" href"next.html"> <link rel"preload" as"style" href"styles.css"> <link rel"preload" as"javascript" hr…

調試工具vue,react,redux

React Developer Tools Redux DevTools Vue devtools 使用瀏覽器官方組件擴展搜索安裝

C語言練習:(力扣645)錯誤的集合

題目鏈接&#xff1a;645. 錯誤的集合 - 力扣&#xff08;LeetCode&#xff09; 集合 s 包含從 1 到 n 的整數。不幸的是&#xff0c;因為數據錯誤&#xff0c;導致集合里面某一個數字復制了成了集合里面的另外一個數字的值&#xff0c;導致集合 丟失了一個數字 并且 有一個數字…

枚舉和聯合(共用體)

目錄 枚舉枚舉類型的定義枚舉的優點 聯合&#xff08;共用體&#xff09;聯合類型的定義聯合的特點聯合大小的計算 枚舉 枚舉顧名思義就是一一列舉&#xff0c;把可能的取值一一列舉 枚舉類型的定義 enum Day &#xff0c; enum Sex &#xff0c;enum Color 都是枚舉類型{}中…

springboot生成圖片驗證碼(借鑒并分析)

目錄 一、CaptchaUtil代碼展示二、CaptchaController 代碼展示 一、CaptchaUtil代碼展示 package com.minster.yanapi.utils;import com.google.code.kaptcha.impl.DefaultKaptcha;import com.google.code.kaptcha.util.Config; import org.springframework.context.annotatio…

MMDetection3D v1.3.0安裝教程

MMDetection3D v1.3.0安裝教程 1. 系統環境2. 安裝2.1 基本環境安裝2.2 調整具體版本2.3 驗證2.4 安裝MinkowskiEngine和TorchSparse 3. 最終環境配置 根據 v1.3.0版本官方手冊測試后的安裝配置&#xff0c;親測可行。 1. 系統環境 項目版本日期Ubuntu18.04.06 LTS-顯卡RTX 2…

曾桂華:車載座艙音頻體驗探究與思考| 演講嘉賓公布

智能車載音頻 I 分論壇將于3月27日同期舉辦&#xff01; 我們正站在一個前所未有的科技革新的交匯點上&#xff0c;重塑我們出行體驗的變革正在悄然發生。當人工智能的磅礴力量與車載音頻相交融&#xff0c;智慧、便捷與未來的探索之旅正式揚帆起航。 在駕駛的旅途中&#xff0…

安裝 Distribution Registry

Distribution Registry是由容器部署&#xff0c;所有前提是需要安裝docker 參考文檔&#xff1a;https://docs.docker.com/engine/install/centos/ Registry 官網文檔 https://distribution.github.io/distribution/ 安裝Registry倉庫 docker run -d -p 5000:5000 --restartalw…

通過css修改video標簽的原生樣式

通過css修改video標簽的原生樣式 描述實現結果 描述 修改video標簽的原生樣式 實現 在控制臺中打開設置&#xff0c;勾選顯示用戶代理 shadow DOM&#xff0c;就可以審查video標簽的內部樣式了 箭頭處標出來的就是shodow DOM的內容&#xff0c;這些內容正常不可見的&#x…

MySQL 用了哪種默認隔離級別,實現原理是什么?

MySQL 的默認隔離級別是 RR - 可重復讀&#xff0c;可以通過命令來查看 MySQL 中的默認隔離級別。 RR - 可重復讀是基于多版本并發控制&#xff08;Multi-Version Concurrency Control&#xff0c;MVCC &#xff09;實現的。MVCC&#xff0c;在讀取數據時通過一種類似快照的方…

視覺三維重建colmap框架的現狀與未來

注&#xff1a;該文章首發3D視覺工坊&#xff0c;鏈接如下3D視覺工坊 前言 眾所周知&#xff0c;三維重建的發展已經進入了穩定期&#xff0c;尤其是離線方案的發展幾乎處于停滯期&#xff0c;在各大論刊上也很少見到傳統sfmmvs亮眼的文章。這也不難理解&#xff0c;傳統的多視…