問題
a: 乙個簡單的整數問題
時間限制
: 5 sec
記憶體限制
: 128 mb
提交: 75
解決: 25
[提交][狀態
][討論版
][命題人
:quanxing
][edit
] [testdata]
題目描述 你有
n個整數,a1,
a2,...,an。
你需要處理兩種操作。
一種操作是在給定間隔中為每個數字新增一些給定數字。
另一種是要求給定間隔中的數字總和。 輸入
第一行包含兩個數字n和
q.1≤n
,q≤100000
。第二行包含
n個數字,a1,
a2,...,
an的初始值。
-1000000000≤ai≤1000000000
。接下來的
q行中的每一行代表乙個操作。
「c a b c」
表示將c
新增到aa
,aa + 1
,...,ab
中的每乙個。
-10000≤c≤10000
。「q a b」
表示查詢aa,
aa + 1
,...,ab
的總和。 輸出
你需要回到
q個詢問,每個詢問一行。
樣例輸入
10 5
1 2 3 4 5 6 7 8 9 10
q 4 4
q 1 10
q 2 4
c 3 6 3
q 2 4
樣例輸出
4559
15
思路:1e5的資料量,暴力區間更新查詢肯定會tle,用線段樹可以快很多,此題是線段樹的模板題。
**:
#includeusing namespace std;
#pragma warning(disable:4996)
#define maxn 100005
#define ll long long
ll chushi[maxn], sum[maxn * 4], lazy[maxn * 4];//記得開4倍空間
void pushup(int rt)
void pushdown(int rt, int len)
}void build(int l, int r, int rt)
int mid = (l + r) / 2;//遞迴建樹——左子樹,右子樹
build(l, mid, 2 * rt);
build(mid + 1, r, 2 * rt + 1);
pushup(rt);//更新父親節點的值
}ll qurry(int x, int y, int l, int r, int rt)
pushdown(rt, r - l + 1);
int mid = (l + r) / 2;
ll ans = 0;
if (x <= mid)ans += qurry(x, y, l, mid, 2 * rt);//如果這個區間的左兒子和目標區間有交集那麼搜尋左兒子
if (y > mid)ans += qurry(x, y, mid + 1, r, 2 * rt + 1);//如果這個區間的右兒子和目標區間有交集那麼搜尋右兒子
return ans;
}void update(int x, int y, int l, int r, int rt, int c)
pushdown(rt, r - l + 1);
int mid = (l + r) / 2;
if (x <= mid)update(x, y, l, mid, 2 * rt, c);
if (y > mid)update(x, y, mid + 1, r, 2 * rt + 1, c);
pushup(rt);
}int main()
else
}}
乙個簡單的整數問題
給定長度為n的數列a,然後輸入m行操作指令。第一類指令形如 c l r d 表示把數列中第l r個數都加d。第二類指令形如 q x 表示詢問數列中第x個數的值。對於每個詢問,輸出乙個整數表示答案。輸入格式 第一行包含兩個整數n和m。第二行包含n個整數a i 接下來m行表示m條指令,每條指令的格式如題...
乙個簡單的整數問題
給定長度為n的數列a,然後輸入m行操作指令。第一類指令形如 c l r d 表示把數列中第l r個數都加d。第二類指令形如 q x 表示詢問數列中第x個數的值。對於每個詢問,輸出乙個整數表示答案。輸入格式 第一行包含兩個整數n和m。第二行包含n個整數a i 接下來m行表示m條指令,每條指令的格式如題...
乙個簡單的整數問題
題目描述給定長度為n的數列a,然後輸入m行操作指令。第一類指令形如 c l r d 表示把數列中第l r個數都加d。第二類指令形如 q x 表示詢問數列中第x個數的值。對於每個詢問,輸出乙個整數表示答案。輸入格式 第一行包含兩個整數n和m。第二行包含n個整數a i 接下來m行表示m條指令,每條指令的...