WEEK5 周记 作业——差分数组_TT的魔法猫
WEEK5 周記 作業——差分數組_TT的魔法貓
一、題意
1.簡述
現有n個城市,第iii個城市有一個資產值a[i]a[i]a[i],每次操作讓區間[l,r][l,r][l,r]中的城市資產增加ccc,要求qqq操作結束后,給出每個城市的資產值。
2.輸入格式
第一行2個整數:nnn,qqq,(1≤n,q≤2×105)(1 \le n,q \le 2 \times 10^5)(1≤n,q≤2×105)——城市的數量和操作的次數。
第二行包含nnn個整數:a1,a2,...an(?106≤ai≤106)a_1,a_2,...a_n(-10^6 \le a_i \le 10^6)a1?,a2?,...an?(?106≤ai?≤106) ——每個城市的資產值。
下面跟著qqq行,每行代表一個操作。每一行有3個數:lll,rrr,ccc(1≤l≤r≤n,?105≤c≤105)(1 \le l \le r \le n,-10^5\le c \le 10^5)(1≤l≤r≤n,?105≤c≤105)。
3.輸出格式
輸出nnn個整數——nnn個城市的最終資產值。
4.樣例
Input_1
4 2
-3 6 8 4
4 4 -2
3 3 1
Output_1
-3 6 9 2
Input_2
2 1
5 -2
1 2 4
Output_2
9 2
二、算法
主要思路
首先看看暴力行不行。最多有2×1052 \times 10^52×105次操作,每次操作最多修改2×1052 \times 10^52×105個值,顯然時間要超過1s。
考慮差分。差分數組可以在O(1)O(1)O(1)的時間復雜度內修改原數組一個區域內的所有元素的值(增/減相同的ccc)。獲取原數組一個元素則需要O(n)O(n)O(n),獲取原數組所有元素的值也只需要O(n)O(n)O(n)。
差分數組的構建:B[1]=A[1]B[1] = A[1]B[1]=A[1]B[i]=A[i]?A[i?1]B[i] = A[i]-A[i-1]B[i]=A[i]?A[i?1]所以∑B[i]=A[i]\sum B[i]= A[i]∑B[i]=A[i]A[L]~A[R]均價上c等價于B[L]+=cB[L] += cB[L]+=cB[R+1]?=cB[R+1] -= cB[R+1]?=c
所以按照公式,每次操作我們只需要花費O(1)O(1)O(1)的時間,最終輸出所有資產值的時間復雜度為O(n)O(n)O(n)。輸出每一個資產值只需要利用公式:A[i]=A[i?1]+B[i]A[i]=A[i-1]+B[i]A[i]=A[i?1]+B[i]就能依次輸出。
題外
小心B數組的數據范圍,這里應該用long long 類型,因為對一個B數組的元素是有可能加q次c的,按照q和c的數據范圍能看出這種情況下用int是會爆精度的。
三、代碼
#include<iostream> #include <cmath> #include<sstream> #include<string> #include<cstdlib> #include<cstring> using namespace std; int a[200010]; long long int b[200010];//又爆了int的精度。。 int main() {int n,q,i,j;scanf("%d%d",&n,&q);for(i=1;i<=n;i++) scanf("%d",&a[i]);b[1]=a[1];for(i=2;i<=n;i++) b[i]=a[i]-a[i-1];for(i=0;i<q;i++){int l,r,c;scanf("%d%d%d",&l,&r,&c);b[l]+=c;b[r+1]-=c;}long long int sum=b[1];printf("%d",sum);if(n>1)printf(" "); for(i=2;i<=n;i++){sum=b[i]+sum;printf("%lld",sum);if(i<=n-1) printf(" ");}return 0; }總結
以上是生活随笔為你收集整理的WEEK5 周记 作业——差分数组_TT的魔法猫的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [HDOJ 4889] Scary Pa
- 下一篇: 寻宝游戏(DFS+动态规划)