Codeforces Round #590 (Div. 3) - E. Special Permutations(差分数组/线段树)

室友这题搞不懂,于是在她出去玩的时候我帮她研究题解…第一次了解了差分数组的知识
差分数组入门: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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值