BZOJ 3295 Cqoi2011動態逆序對

2021-09-12 05:43:33 字數 1580 閱讀 2840

題目

憑弔我以前沒過的3kb**和現在的1.2kb**,哎。

ia_i

ai​,數的大小為b

ib_i

bi​,插入時間為c

ic_i

ci​那麼對於a

i

且b

i>bj

a_ib_j

ai​​且bi

​>bj

​的每對數都會給c

ic_i

ci​較大的數的插入增加逆序對數+1。

然後可以對a,b或c分治。

對c分治是最簡單的,因為肯定是前半區間對後半區間貢獻,

但如果對a,b分治,那就需要兩個樹狀陣列了,因為後半區間也可以對前半區間貢獻。。。。。。

ac code(加了讀優所以變長了)

#include

#define maxn 100005

#define ll long long

using

namespace std;

char cb[

1<<15]

,*cs=cb,

*ct=cb;

#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)

inline

void

read

(int

&res)

int n,m,tr1[maxn]

,tr2[maxn]

,a[maxn]

,b[maxn]

,pt[maxn]

,tmp[maxn]

,c[maxn]

,loc[maxn]

;ll ans[maxn]

;inline

void

upd(

int*tr,

int now,

int val)

inline

intqsum

(int

*tr,

int now,

int ret=0)

void

solve

(int l,

int r)

else

}for

(int i=l;i<=r;i++)}

intmain()

for(

int i=

1;i<=n;i++)if

(!b[i]

) b[i]=1

;solve(1

,n);

for(

int i=

1;i<=n;i++

) ans[b[i]]+

=pt[i]

;for

(int i=

2;i<=m+

1;i++

) ans[i]

+=ans[i-1]

;for

(int i=m+

1;i>=

2;i--

)printf

("%lld\n"

,ans[i]);

}

bzoj3295 CQOI2011 動態逆序對

time limit 10 sec memory limit 128 mb submit 3122 solved 986 submit status discuss 對於序列a,它的逆序對數定義為滿足i aj 的數對 i,j 的個數。給1到n的乙個排列,按照某種順序依次刪除m個元素,你的任務是在每次...

Cqoi2011 BZOJ3295 動態逆序對

對於序列a,它的逆序對數定義為滿足i 樹狀陣列 一看到逆序對就要想到樹狀陣列。維護每個數前面到目前有多少個比自己大。動態的思路 因為要動態維護,每次只刪掉乙個數在逆序對中的貢獻 及每個數前面有多少個比自己大,每個數後面有多少數比自己小。先預處理出每個數前面有多少個比自己大ll i 每個數後面有多少個...

bzoj3295 Cqoi2011 動態逆序對

傳送門 題解 cdq分治 我們仔細想一想維護逆序對的時候我們用的不就是歸併排序嗎?而歸併排序不就可以看作一種分治嗎?於是此題走上正軌,我們可以用分治來寫 怎麼寫?我們刪除乙個點,損失了什麼?1.這個點x之前比我大的個數記為big x 這個點x之後比我小的記作small x 那麼損失 small x ...