time limit: 10 sec memory limit: 128 mb
submit: 7178 solved: 2548
[submit][status][discuss]
對於序列a,它的逆序對數定義為滿足iaj的數對(i,j)的個數。給1到n的乙個排列,按照某種順序依次刪
除m個元素,你的任務是在每次刪除乙個元素之前統計整個序列的逆序對數
輸入第一行包含兩個整數n和m,即初始元素的個數和刪除的元素個數。
以下n行每行包含乙個1到n之間的正整數,即初始排列。
以下m行每行乙個正整數,依次為每次刪除的元素。
n<=100000 m<=50000
輸出包含m行,依次為刪除每個元素之前,逆序對的個數。
5 4153
4251
4252
21思路:這是一道十分經典的題目。可以用cdq分治做,也可以用樹套樹做。不過做樹套樹身體會被掏空的,還是cdq好了。。。
之前一直不太了解cdq分治,雖然聽說過它的威名,卻一直沒能學會。今天突擊了一下,算是剛入了點門吧(可能連門都沒入)
如同網上大佬們所說的,一般三維的cdq問題,第一位排序,第二維分治,第三位資料結構(bit)。。。
本蒟蒻就照著這個做了。不過之前一直沒能理解別人的**中額外開乙個陣列記錄是什麼意思,後來在汪聚聚的講解下明白了這是歸併操作(話說我是不是學了個假的分治。。。)
這道題具體思路可以看:
主要思想就是將每個點抽象成乙個三元組(位置,數,時間戳)。而上面的做法的巧妙之處在於將刪點轉化為加點(時間戳反向就行了)。所以這道題變成了第一位排序時間戳,第二維cdq位置,第三維用bit位數它前面的數。由於每個點要統計前面和後面的點,所以要跑兩次cdq。。。
**:
#includeusing namespace std;
typedef long long ll;
const int maxn=1e5+10;
typedef struct
c;c c[maxn];
int pos[maxn];
c res[maxn];
ll tot=0;
ll mx;
int n,m;
bool cmp1(c a, c b)
res[++tot]=c[i];
ans[c[i].t]+=ask(c[i].x+1);
} for(int i=l;ifor(int i=ptr;i<=m;i++)
res[++tot]=c[i];
for(int i=l;i<=r;i++) }
int main()
for(int i=1;i<=m;i++)
sort(c+1,c+1+n,cmp1);
solve(1,n);
for (int i=1;i<=n;++i)
sort(c+1,c+1+n,cmp1);
solve(1,n);
for(int i=1;i<=n;i++)
for(int i=1;i<=m;i++)
return 0;
}
bzoj3295 動態逆序對
portal bzoj3295 雖然說這個可能原本是一道愉快的樹套樹但是 看到 按照某個順序依次刪除 這樣的字眼,比較容易聯想到乙個套路 反過來看,變成按照某個順序依次插入 那麼對於乙個詢問,刪掉它之前 化完了之後就是插入它之後 的所會影響到的逆序對數可以分為兩種 一種是在它前面但是比它大的,一種是...
BZOJ3295 動態逆序對
問題描述 對於序列a,它的逆序對數定義為滿足i j,且ai aj的數對 i,j 的個數。給1到n的乙個排列,按照某種順序依次刪除m個元素,你的任務是在每次刪除乙個元素之前統計整個序列的逆序對數。輸入格式 輸入第一行包含兩個整數n和m,即初始元素的個數和刪除的元素個數。以下n行每行包含乙個1到n之間的...
BZOJ3295 動態逆序對(樹狀陣列套線段樹)
time limit 10 sec memory limit 128 mb submit 6058 solved 2117 submit status discuss 對於序列a,它的逆序對數定義為滿足i aj 的數對 i,j 的個數。給1到n的乙個排列,按照某種順序依次刪除m個元素,你的任務是在每...