洛谷p3347
已知乙個數列,你需要進行下面兩種操作:
1.將某乙個數加上x
2.求出某區間每乙個數的和
輸入格式:
第一行包含兩個整數n、m,分別表示該數列數字的個數和操作的總個數。
第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。
接下來m行每行包含3個整數,表示乙個操作,具體如下:
操作1: 格式:1 x k 含義:將第x個數加上k
操作2: 格式:2 x y 含義:輸出區間[x,y]內每個數的和
輸出格式:
輸出包含若干行整數,即為所有操作2的結果。
輸入樣例#1:複製
5 5
1 5 4 2 3
1 1 3
2 2 5
1 3 -1
1 4 2
2 1 4
輸出樣例#1:複製
14
16
時空限制:1000ms,128m
資料規模:
對於30%的資料:n<=8,m<=10
對於70%的資料:n<=10000,m<=10000
對於100%的資料:n<=500000,m<=500000
樣例說明:
故輸出結果14、16
#includeusing namespace std;
int n,m,d[501000];
struct nodet[501000*4];//注意:這裡為什麼要開四倍空間
void build(int k,int l,int r)
int mid=(l+r)/2;
build(k*2,l,mid);
build(k*2+1,mid+1,r);//思考:為什麼左子樹的編號是k*2,右子樹的編號是k*2+1;
t[k].sum=t[k*2].sum+t[k*2+1].sum;
} //建立線段樹
void update(int k,int pos,int w)
int mid=(t[k].l+t[k].r)/2;
if(pos<=mid) update(k*2,pos,w);//如果目標位置在左子樹中
if(mid
t[k].sum=t[k*2].sum+t[k*2+1].sum;//子樹中的節點改變 那麼相應的改變父親節點的區間和
} int ask(int k,int l,int r)
int mid=(t[k].l+t[k].r)/2,ans=0;
if(l<=mid)ans+=ask(k*2,l,r);//左子樹中 包含目標區間的 點
if(mid
return ans;
}int main()
if(op==2)
} return 0;
}
線段樹 建樹 單點修改 單點 區間查詢
線段樹 sgement tree 是一種分治思想的二叉樹結構,用於在區間上進行資訊統計。與按照二進位制位進行區間劃分的樹狀陣列相比,線段樹是一種更加通用的結構 1.線段樹的每個節點都代表乙個區間。2.線段樹具有唯一的根節點,代表的區間是整個統計範圍,如 1,n 3.線段樹的每個葉節點都代表乙個長度為...
操作格仔 單點修改線段樹
問題描述 有n個格仔,從左到右放成一排,編號為1 n。共有m次操作,有3種操作型別 1.修改乙個格仔的權值,2.求連續一段格仔權值和,3.求連續一段格仔的最大值。對於每個2 3操作輸出你所求出的結果。輸入格式 第一行2個整數n,m。接下來一行n個整數表示n個格仔的初始權值。接下來m行,每行3個整數p...
線段樹單點修改區間查詢
這是一道模板題。給定數列 a 1 a 2 a n 你需要依次進行 qq 個操作,操作有兩類 1 i x 給定 i,x,將 a i 加上 x 2 l r 給定 l,r,求 ri la i 的值 換言之,求 a l a l 1 a r 的值 input 第一行包含 2 個正整數 n,q,表示數列長度和詢...