BZOJ 2141 排隊 CDQ分治

2021-09-07 09:50:31 字數 1490 閱讀 8362

題意:

交換序列中兩個元素,求逆序對

做分塊做到這道題...一看不是三維偏序嘛....

作為不會樹套樹的蒟蒻就寫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個...