題意:
交換序列中兩個元素,求逆序對
做分塊做到這道題...一看不是三維偏序嘛....
作為不會樹套樹的蒟蒻就寫cdq分治吧....
對時間分治...x排序...y樹狀陣列...
交換拆成兩個插入兩個刪除,儲存一下型別就行了
才發現逆序對問題的刪除操作不用時間倒流也可以,直接減去它形成的逆序對數並且在樹狀陣列中刪除就可以了
然後愚蠢的我竟然把操作的時間弄成相同的調了一會才覺得不對....
#include #include#include
#include
using
namespace
std;
typedef
long
long
ll;const
int n=1e5+5
;inline
intread()
while(c>='
0'&&c<='9')
return x*f;
}int
n,q,a[n],mp[n];
intm,tim;
struct
meow
meow(
int a,int b,int c,int d,int e=0
):t(a),x(b),y(c),type(d),qid(e){}
bool
operator
<(const meow &r) const
}q[n],t[n];
intans[n];
intc[n];
inline
void add(int p,int v)
inline
int sum(int p)
void cdq(int l,int
r)
for(int i=l;i<=r;i++) if(q[i].t<=mid) add(q[i].y,-q[i].type);
for(int i=r;i>=l;i--)
for(int i=l;i<=r;i++) if(q[i].t<=mid) add(q[i].y,-q[i].type);
int p1=l,p2=mid+1
;
for(int i=l;i<=r;i++)
for(int i=l;i<=r;i++) q[i]=t[i];
cdq(l,mid); cdq(mid+1
,r);
}int
main()
sort(q+1,q+1+m);
cdq(
1,m);
printf(
"%d\n
",ans[0
]);
for(int i=1;i<=q;i++) ans[i]+=ans[i-1],printf("
%d\n
",ans[i]);
}
bzoj2141 排隊 cdq分治
和動態逆序對有些類似 這題既可以以時間為第一維 也可以以x軸維第一維度 具體視題目而定 cdq分治只能求點對之間的影響 如果要變成整個序列的情況 那麼可以用字首和 一開始的原序列的id設定成0即可 includeusing namespace std define rep i,a,b for int...
BZOJ 2141 排隊 分塊 Treap
排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你乙個,我乙個,大的分給你,小的留給我,吃完果果唱支歌,大家樂和和。紅星幼兒園的小朋友們排起了長長地隊伍,準備吃果果。不過因為小朋友們的身高有所區別,排成的隊伍高低錯亂,極不美觀。設第i個小朋友的身高為hi,我們定義乙個序列的雜亂程度為 滿足ihj的 i,j ...
分塊入門 bzoj2141排隊
to infinity and beyond.wall e 首先可以用離散化 樹狀陣列來計算逆序對個數 時間複雜度 n log n 對於有關逆序對的題目,首先可以想到逆序對的特質 然後對於每個詢問 x,y xa i a i a x ans a i a i a y ans 此時想到用分塊處理 對於n個...