室友这题搞不懂,于是在她出去玩的时候我帮她研究题解…第一次了解了差分数组的知识
差分数组入门:https://www.cnblogs.com/COLIN-LIGHTNING/p/8436624.html 写的真的很好,一康就懂惹qwq
就是遍历所有对相邻两个的值的位置差,把他们对所有pi序列的函数值的贡献值加进去。(用差分数组/线段树实现区间加减操作,并可快速得到前缀和)
#include <iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
ll s[200010], x[200010];
//s[l]加上变量v,s[r+1]减去变量v
void up(int l, int r, int v){
s[l] += v;
s[r+1] -= v;
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
scanf("%lld", &x[i]);
for(int i = 2; i <= m; i++){
int l = x[i-1], r = x[i];//取x数组里相邻俩个元素
if(l > r) swap(l, r);//保证l是较小的那个
if(l != r){//如果l不等于r
//s[l]加上变量v,s[r+1]减去变量v
up(1, l-1, r-l);//s[1]加上r-l
up(l, l, r-1);//i=l的时候,l,r贡献是r-1
up(l+1, r-1, r-l-1);//pi (l<i<r),l,r贡献是r-l-1,两者位置小于1~
up(r,r,l);//pr,l,r贡献是l
up(r+1,n,r-l);//pi,r<i<=n,贡献是r-l,无影响啦~!
}
}
for(int i = 1; i <= n; i++)
printf("%lld ",s[i] += s[i-1]);
//emm?怎么啦。
return 0;
}