设数组 data[]={1,6,8,5,10},那么差分数组 different[]={1,5,2,-3,5} 也就是说 different[i]=data[i]-data[i-1] (data[0]=0);
那么 data[i]= ∑ d o w n = 1 i b [ d o w n ] \sum_{down=1}^i b[down] \frac{}{} ∑down=1ib[down]
假如区间[2,4]都加上2的话 此时 data[]={1,8,10,7,10}; different[]={1,7,2,-3,3}
发现 different 数组只有different[2]和different[5]变了,因为区间[2,4]是同时加上2的,所以区间内 different[i]~different[i-1]是不变的
当我们对一个区间[x,y]进行修改的时候,只需要对它的差分数组进行修改,只需要修改 different[x]和different[y+1];
由于巨人们的进攻,人类的生活圈已经越来越小。某一年,巨人又开始对南方的围墙发起猛攻,但是南方围墙非常坚固,巨人无法攻进去。不过巨人在某一天感染了一种特殊病毒,这种病毒可以让巨人长高。长高的巨人就可以突破围墙了,这令南方的守城兵长非常恐慌,他不断派人把围墙修改以抵挡敌人的进攻。最后巨人终于停止了这一波攻击。士兵长想知道现在每一堵墙有多高。
输入 第一行两个数n,m表示有n堵围墙,m次修墙
接下来一行n个数为围墙的初始高度。
接下来m行每行3个数Li,Ri,Xi,表示第Li到Ri堵围墙都增高Xi米
输出 一行n个数:第i个数表示编号为i的墙的最后高度。
样例输入 5 2 1 2 3 4 5 1 5 1 2 4 1 样例输出 2 4 5 6 6 【数据范围】 对于30%的数据:1 ≤ n、m ≤ 1000。
对于60%的数据:1 ≤ n、m ≤ 100000。
对于100%的数据:1 ≤ n、m ≤ 700000,1 ≤ Li ≤ Ri ≤ n,1 ≤ Xi ≤ 1000。
#include<cstdio> #include<iostream> using namespace std; typedef unsigned long long ull; #define digit 700001 ull data[digit],record[digit]; ull length,times; void enter() { record[0]=0; record[length+1]=0; scanf("%lld%lld",&length,×); for(ull i=1;i<=length;i++) scanf("%lld",&data[i]), record[i]=data[i]-data[i-1]; ull x,y,addsum; while(times--) { scanf("%lld%lld%lld",&x,&y,&addsum); record[x]+=addsum; record[y+1]-=addsum; } ull sum=0; for(ull i=1;i<=length;i++) { sum+=record[i]; printf("%lld ",sum); } } int main() { enter(); return 0; }以后对于区间内加减法并要求输出的题都可以考虑一下 差分算法
感谢 Lyp10000