題目描述
你現在有乙個陣列 aa
我們定義如下的兩種操作:
1. 修改: 形如 00 ll rr ,效果為對所有 l<=i<=rl<=i<=r 執行 ai+=(i−l+1)ai+=(i−l+1)
直觀地說就是al+=1,al+1+=2,al+2+=3 ... ar+=r−l+1al+=1,al+1+=2,al+2+=3 ... ar+=r−l+1 這個樣子
2. 查詢: 形如 11 ll rr , 要求輸出此時的 ∑ri=lai∑i=lrai 的值
一開始當然整個陣列都是0啦
輸入描述
第一行乙個整數q表示操作總數
接下來q行, 每行乙個操作(格式參考題目描述)
輸出描述
對於每個查詢, 輸出一行, 表示此時的 ∑ri=lai∑i=lrai 的值
樣例輸入
3樣例輸出0 1 2
0 3 4
1 1 4
6資料範圍
1<=q,l,r<=105
最近給學弟學妹講線段樹,發現以前這道題並沒有補,就給補上了。
對於乙個區間每個位置要加上對應的數 [1 2 3 4 5 6 ...]
若把上述區間分成左右區間就變成了 [1 2 3] [4 5 6]
a b
由於 [4 5 6] = [1 2 3] + [3 3 3]
所以需要兩個懶惰標記,lazy1記錄這個區間裡有多少個等差數列(a部分),lazy2記錄這個區間的每個數要加上多少(b部分)
**如下:
#include#define n 100010
#define ll long long
using namespace std;
struct node
eg[n];
ll sum[n<<2],lazy1[n<<2],lazy2[n<<2];
void pushup(int o)
void pushdown(int o,ll len)
}void update(int x,int y,int l,int r,int o)
pushdown(o,(ll)r-l+1);
int mid=(l+r)>>1;
if(x<=mid)update(x,y,l,mid,o<<1);
if(y>mid)update(x,y,mid+1,r,o<<1|1);
pushup(o);
}ll query(int x,int y,int l,int r,int o)
int main()
for(int i=0;ireturn 0;
}
C E 等差數列求和
題目 要求給定乙個整數 n,求從 0 到 n 之間所有整數相加之和。解1 使用 for 迴圈依次遞加。include int main void int sum int x return result 解2 題目所求實際上為乙個首項為 0,末項為 n,公差為 1 的等差數列,根據等差求和公式 s n...
C E 等差數列求和
題目 要求給定乙個整數 n,求從 0 到 n 之間所有整數相加之和。解1 使用 for 迴圈依次遞加。include int main void int sum int x return result 解2 題目所求實際上為乙個首項為 0,末項為 n,公差為 1 的等差數列,根據等差求和公式 s n...
牛牛的等差數列 線段樹
這裡的突破口在於小於等於25且大於等於3的質數連乘在1e8左右,所以,我們可以在操作上,將其看作對1e8去求模,而不是對每個都進行預處理。時間複雜度 include include include include include include include include include inc...