P3157 動態逆序對 CDQ分治

2021-09-25 06:08:16 字數 1615 閱讀 5003

傳送門:

對於序列a,它的逆序對數定義為滿足iaj的數對(i,j)的個數。給1到n的乙個排列,按照某種順序依次刪除m個元素,你的任務是在每次刪除乙個元素之前統計整個序列的逆序對數。

這個題是告訴你如何將乙個問題轉換為三維偏序問題

首先,求解逆序對,那麼a.val>b.val,刪除乙個元素的時間是t,a.t對於這個三維偏序問題,我們就可以採用cdq分治給解決,逆序對的統計可以套乙個樹狀陣列解決

#include #include #include #include #include #include #include #include #include using namespace std;

typedef long long ll;

typedef pairpii;

typedef unsigned long long ull;

#define ls rt<<1

#define rs rt<<1|1

#define lson l,mid,rt<<1

#define rson mid+1,r,rt<<1|1

#define bug printf("*********\n")

#define fin freopen("input.txt","r",stdin);

#define fon freopen("output.txt","w+",stdout);

#define io ios::sync_with_stdio(false),cin.tie(0)

#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"

#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"

#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<> 1;

cdq(l, mid);

cdq(mid + 1, r);

sort(a + l, a + mid + 1, cmpd);

sort(a + mid + 1, a + r + 1, cmpd);

int j = l;

for(int i = mid + 1; i <= r; ++i)

ans[a[i].id] += a[i].m * (sum(n) - sum(a[i].v));

}for(int i = l; i < j; i++)

j = mid;

for(int i = r; i > mid; i--)

ans[a[i].id] += a[i].m * sum(a[i].v - 1);

}for(int i = mid; i > j; i--)

}int match[maxn];

int main()

for(int i = 1, x; i <= m; i++)

cdq(1, tot);

for(int i = 1; i <= m; i++)

for(int i = 0; i < m; i++)

return 0;

}

動態逆序對 CDQ分治

對於序列a,它的逆序對數定義為滿足iaj的數對 i,j 的個數。給1到n的乙個排列,按照某種順序依次刪除m個元素,你的任務是在每次刪除乙個元素之前統計整個序列的逆序對數。輸入格式 輸入第一行包含兩個整數n和m,即初始元素的個數和刪除的元素個數。以下n行每行包含乙個1到n之間的正整數,即初始排列。以下...

P3157 CQOI2011 動態逆序對

題目描述 現在給出 1 n 的乙個排列,按照某種順序依次刪除 m 個元素,你的任務是在每次刪除乙個元素之前統計整個序列的逆序對數。輸入格式 第一行包含兩個整數 n和 m,即初始元素的個數和刪除的元素個數。以下 n 行,每行包含乙個 1 n 之間的正整數,即初始排列。接下來 m 行,每行乙個正整數,依...

P3157 CQOI2011 動態逆序對

對於序列a,它的逆序對數定義為滿足iaj的數對 i,j 的個數。給1到n的乙個排列,按照某種順序依次刪除m個元素,你的任務是在每次刪除乙個元素之前統計整個序列的逆序對數。輸入格式 輸入第一行包含兩個整數n和m,即初始元素的個數和刪除的元素個數。以下n行每行包含乙個1到n之間的正整數,即初始排列。以下...