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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章