樹狀陣列
1.小朋友排隊
n'>n
個小朋友站成一排。
現在要把他們按身高從低到高的順序排列,但是每次只能交換位置相鄰的兩個小朋友。
每個小朋友都有乙個不高興的程度。
開始的時候,所有小朋友的不高興程度都是 0
'>0
。如果某個小朋友第一次被要求交換,則他的不高興程度增加 1
'>1
,如果第二次要求他交換,則他的不高興程度增加 2
'>2
(即不高興程度為 3
'>3
),依次類推。當要求某個小朋友第 k
'>k
次交換時,他的不高興程度增加 k
'>k
。請問,要讓所有小朋友按從低到高排隊,他們的不高興程度之和最小是多少。
如果有兩個小朋友身高一樣,則他們誰站在誰前面是沒有關係的。
輸入格式
輸入的第一行包含乙個整數 n
'>n
,表示小朋友的個數。
第二行包含 n
'>n
n 個整數 h1,
h2,…
,hn'>h1,h2,…,hn
,分別表示每個小朋友的身高。
輸出格式
輸出一行,包含乙個整數,表示小朋友的不高興程度和的最小值。
資料範圍1≤
n≤100000
'>1≤n≤1000000≤
hi≤1000000
'>0≤hi≤1000000
輸入樣例:
3
3 2 1
輸出樣例:9
樣例解釋
首先交換身高為3和2的小朋友,再交換身高為3和1的小朋友,再交換身高為2和1的小朋友,每個小朋友的不高興程度都是3,總和為9。
解題思路:解題關鍵就是找到最少的交換次數,我們可能會想到氣泡排序法,他就是通過不斷的交換排序來實現的,因此我們可以大膽的假設一些規律,最少的交換次數==逆序對的個數。
對於氣泡排序來說,每次交換最多減少乙個逆序數
假設陣列有k個逆序對,
①至少需要交換k次,因此次數》=k
②在氣泡排序中,每次交換(ai,ai+1)且ai>ai+1,因此必然會使逆序數減1
綜上我們得出最少的交換次數==逆序對的個數
接下來,我們要求每乙個小朋友的逆序數,然後根據前n項和公式求出他的不高興數,在求解單個逆序數時,我們就用到樹狀陣列來統計在該陣列中,前方大於他的數和後方小於他的數,總和即為該數的逆序數。
**:
#include#includeusing
namespace
std;
typedef
long
long
ll;const
int n=1000010
;int
tr[n],h[n];
ll con[n];
intn;
int lowbit(int
x)void add(int x,int
v)int query(int
x)int
main()
//計算前面比他大的數
long
long ans=0
;
for(i=0;i)
//計算後面比它小的數
memset(tr,0,sizeof
(tr));
for(i=n-1;i>=0;i--)
//總和
for(i=0;i)
ans+=con[i]*(con[i]+1)/2
; cout
}
差分1.差分
輸入乙個長度為n的整數序列。
接下來輸入m個操作,每個操作包含三個整數l, r, c,表示將序列中[l, r]之間的每個數加上c。
請你輸出進行完所有操作後的序列。
輸入格式
第一行包含兩個整數n和m。
第二行包含n個整數,表示整數序列。
接下來m行,每行包含三個整數l,r,c,表示乙個操作。
輸出格式
共一行,包含n個整數,表示最終序列。
資料範圍1≤
n,m≤
100000
'>1≤n,m≤100000,1
≤l≤r
≤n'>1≤l≤r≤n,−
1000≤c
≤1000
'>−1000≤c≤1000,−
1000≤整
數序列中
元素的值
≤1000
'>−1000≤整數序列中元素的值≤10001≤
n,m≤
100000
'>1≤l
≤r≤n
'>−
1000≤c
≤1000
'>−
1000≤整
數序列中
元素的值
≤1000
'>解題思路:
給定a[1],a[2],...a[n]構造查分陣列b[n],使得
a[i]=b[1]+b[2]+...b[i]
核心操作:將a[l~r]全部加上c,等價於b[l]+=c,b[r+1]-=c
1.a[1~l-1]無影響
2.a[l~r]加上了c
3.a[r+1~n]無影響
#includeusingnamespace
std;
const
int n=100010
;int
b[n],q[n];
void insert(int l,int r,int
c)int
main()
for(i=1;i<=n;i++)
return0;
}
樹狀陣列與線段樹
推一下關於樹狀陣列的講解部落格 和線段樹的講解 package test2 public class 線段樹 int len a.length segtree t buildtree 0,len 1,a int sum0 2 query t,0,2 int sum1 3 query t,1,3 查詢...
樹狀陣列與線段樹(三)
找規律題 1.螺旋折線 如下圖所示的螺旋折線經過平面上所有整點恰好一次。對於整點 x,y 我們定義它到原點的距離 dis x,y 是從原點到 x,y 的螺旋折線段的長度。例如 dis 0,1 3,dis 2,1 9 給出整點座標 x,y 你能計算出 dis x,y 嗎?輸入格式 包含兩個整數 x,y...
線段樹與樹狀陣列學習總結 線段樹
點動成線 那麼就是說一條線段可以分成若干個點,再想想我們最常用的一維陣列,構成陣列的是乙個個的變數,如果把變數看成乙個個點,那麼陣列就是一條線了!而線段樹,就是一棵由線段構成的二叉樹,每個結點都代表一條線段 a,b 也就是我們前面說的一串變數 非葉子的結點所對應的線段都有兩個子結點,左兒子代表的線段...