對於序列a,它的逆序對數定義為滿足iaj的數對(i,j)的個數。給1到n的乙個排列,按照某種順序依次刪除m個元素,你的任務是在每次刪除乙個元素之前統計整個序列的逆序對數。
可以值域分塊,塊套樹狀陣列,樹套樹
不過用序列分塊\(+vector\)一樣能水過這道題
考慮刪去乙個點\(x\)對答案產生的影響,拿下面的數列來說
\[1,2……x……n-1,n
\]
對於區間\([1,x-1]\),\(a_i>a_x\)會產生逆序對
對於區間\([x+1,n]\),\(a_i會產生逆序對那麼每次刪點後統計一下\(x\)兩側滿足條件的數就好了
我們對序列分塊,同乙個塊裡的用\(vector\)排好序,和\(x\)在不同塊的二分查詢更新答案,和\(x\)在同乙個塊的暴力列舉更新答案,每次刪點的時候在\(vector\)裡刪除點就好了
複雜度大約是\(o(mlog(n)\sqrt)\),吸吸氧就過了
code
#include #include #include #include #include #include #define n 100000
#define rep(i,s,t) for (register int i=s;i<=t;i++)
#define drep(i,s,t) for (register int i=t;i>=s;i--)
#define il inline
using namespace std;
int n,m,a[n+5],data[n+5],bs,blo[n+5],l[n+5],r[n+5],na[n+5],d[n+5],id[n+5],cnt;
long long ans;
vector p[n+5];
void merge_sort(int l,int r)
}rep(i,l,r)
data[i]=na[i];
}}il void del(int x)
il void calc(int x)
il int read()
int main()
merge_sort(1,n);
rep(i,1,blo[n])
sort(p[i].begin(),p[i].end());
int x;
rep(i,1,m)
return 0;
}
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之間的正整數,即初始排列。以下...
P3157 CQOI2011 動態逆序對
傳送門 設 val i 為位置 i 的值 維護 ansl i 表示位置 i 的數左邊所有大於 val i 的數的數量 維護 ansr i 表示位置 i 的數右邊所有小於 val i 的數的數量 考慮先求出一開始總的逆序對數 ans 每次刪除乙個數 位置為 p 就把 ans 減去 ansl p ans...