Cqoi2011 動態逆序對

2021-08-14 06:50:43 字數 1406 閱讀 3754

主席樹套樹狀陣列。

主席樹第一題。

鏈結靜態的逆序對問題很簡單,用線段樹或者是樹狀陣列即可解決。

現在的問題是如何解決一道動態的逆序對問題?

我們先把所有的逆序對統計出來。

每次刪除數,我們可以把這個數對於逆序對個數的貢獻刪除出去。

這個貢獻如何統計呢?

front[i]記錄i位置之前有多少個數比這個數大

back[i]記錄i位置之後有多少個數比這個數小

每次刪除的貢獻就是這兩個數之和

放屁!如果之前我們已經刪除過了一些資料,不就減少的多了?

如何統計呢?

把刪除的數扔入主席樹。

而查詢前面多少個比這個數大的,和後面多少個數比這個小,主席樹的基本功能!

需要注意的是。

本題要開long long。

本題也可以通過cdq分治以及暴力分塊的方法解決。

日後想起來在寫!(主要是不會。)

#include 

#include

#include

#define il inline

#define lowbit(x) x&-x

#define ll long long

using namespace std;

const int maxm=1e6+100;

int root[maxm];

int sum[maxm<<5],lson[maxm<<5],rson[maxm<<5];

int front[maxm],back[maxm];

int tree[maxm],pos[maxm],val[maxm];

int a[maxm],b[maxm];

int n,m,size;

il ll ask(int

x)il void up(int

x)inline void updata(int &o,int l,int r,int valx)

il ll ask_big(int l,int r,int valx)

else

}return ans;

}il ll ask_less(int l,int r,int valx)

else

}return ans;

}int main()

memset(tree,0,sizeof(tree));

for(int i=n;i>=1;i--)

back[i]=ask(val[i]-1),up(val[i]);

//printf("%d\n",m);

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

//printf("--%d--\n",ans);

return

0;}

CQOI2011 動態逆序對

這是一道cdq分治的好題,這道題的前置知識是cdq分治解決三維偏序問題,如果不會這個話請先自行學習。首先第乙個答案很顯然就是逆序對的數量,然後後面每次的刪除操作,我們考慮把這個被刪除的點原先的貢獻從答案中拿掉。我們用y表示這個點的數,del表示第幾個被刪除,若沒有被刪除則del m 1 考慮每個點的...

CQOI2011 動態逆序對

點此看題 考慮c dq cdqcd q,有三個值 t,d,v t,d,v t,d,v 要求t i t iti d i d idi v i vj v i v j vi vj 很容易看出來是三維偏序的板題,我們先保證t tt的有序,cdq cdqcd q的時候排序d dd,然後用樹狀陣列查詢v vv,貼...

CQOI2011 動態逆序對

使用樹狀陣列求出初態下出f i g i 表示位置小 大 於i且值大 小 於a i 的元素個數。顯然ans 初 sum f i sum g i 考慮第乙個刪去的點x,刪去以後,ans減少f x g x 再考慮第二個刪去的點y,刪去以後,ans減少f y g y 不,f y g y 中可能算上了x 此題...