日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[Codevs] 1081 线段树练习 2 ----“分块!”

發布時間:2025/3/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Codevs] 1081 线段树练习 2 ----“分块!” 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1081 線段樹練習 2

?時間限制: 1 s ?空間限制: 128000 KB ?題目等級 : 大師 Master 題目描述?Description

給你N個數,有兩種操作


1:給區間[a,b]的所有數都增加X

2:詢問第i個數是什么?

?

輸入描述?Input Description

第一行一個正整數n,接下來n行n個整數,再接下來一個正整數Q,表示操作的個數. 接下來Q行每行若干個整數。如果第一個數是1,后接3個正整數a,b,X,表示在區間[a,b]內每個數增加X,如果是2,后面跟1個整數i, 表示詢問第i個位置的數是多少。

輸出描述?Output Description

對于每個詢問輸出一行一個答案

樣例輸入?Sample Input

3

1?2?3

2

1 2 3 2

2 3

樣例輸出?Sample Output

5

數據范圍及提示?Data Size & Hint

數據范圍

1<=n<=100000

1<=q<=100000

?

分析 Analysis

qwq闊別一年,終于能用分塊寫啦!

這段時間在網上翻了一些博客,也翻了藍書和ACM模版小紅書,發現分塊寫法風格實在是多樣

像ACM紅書(就清華大學出版社+俞勇主編那本ACMXXX《算法與實現》),里面寫成了純鏈表

藍書寫的就比較接近我現在的習慣,但是也是難以模仿

現在的分塊類型總結如下:

A. 將數據完全存在各種塊中(就是紅書那種塊狀鏈表,一個節點保存一塊的信息)

B. 將數據存在線性數組中,分塊相關的附屬信息用另外一個結構存,線性數組中每一個元素有對應的塊編號

個人覺得B. 比較好寫(其實是因為B.寫對了)

個人覺得寫的比較好的分塊范例是在 1081線段樹練習2 的題解里找到的,推薦!

顯然,分塊的風格還是挺多的

之前也聽學長說分塊很難寫(因為細節部分容易出錯)還難調(我是挺難調的= =)

不過還是推薦學一學

?

代碼 Code

1 #include<cstdio> 2 #include<cmath> 3 #include<iostream> 4 #define maxn 1000000 5 using namespace std; 6 7 int size,arr[maxn],block[maxn],add[maxn],n,q,swi,a,b,c; 8 9 void modify(int a,int b,int c){ 10 a--,b--; 11 for(int i = a;i <= min(block[a]*size-1,b);i++) 12 arr[i] += c; 13 if(block[a] != block[b]){ 14 for(int i = (block[b]-1)*size;i <= b;i++) 15 arr[i] += c; 16 } 17 for(int i = block[a]+1;i < block[b];i++) 18 add[i] += c; 19 } 20 21 int main(){ 22 scanf("%d",&n); 23 size = (int)sqrt(n); 24 for(int i = 0;i < n;i++) scanf("%d",&arr[i]); 25 for(int i = 0;i < n;i++) block[i] = i/size+1; 26 // for(int i = 0;i < n;i++) printf("#%d: block->%d\n",i+1,block[i]); 27 scanf("%d",&q); 28 for(int i = 1;i <= q;i++){ 29 scanf("%d",&swi); 30 if(swi%2){ 31 scanf("%d%d%d",&a,&b,&c); 32 // for(int i = 1;i <= n;i++) printf("#%d: add->%d\n",i,add[block[i]]); 33 modify(a,b,c); 34 }else{ 35 scanf("%d",&a); 36 printf("%d\n",arr[a-1]+add[block[a-1]]); 37 } 38 } 39 40 // for(int i = 0;i < n;i++) printf("#%d: block[%d]\n",i,block[i]); 41 42 return 0; 43 } 分塊!

?

轉載于:https://www.cnblogs.com/Chorolop/p/7512248.html

總結

以上是生活随笔為你收集整理的[Codevs] 1081 线段树练习 2 ----“分块!”的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。