CDQ分治 用時間降維的美麗演算法

2021-08-21 07:59:16 字數 2888 閱讀 7745

cdq分治,網上的闡述很多,太專業性的文字我就不贅述,這裡指談談自己的感受

還是%一下cdq大神的**

cdq分治的主要想法就是降維(比如三維問題降維到二維問題),並付出o(

logn

) o(l

ogn)

的代價

前提:支援離線

那麼我們思考一下經典二維偏序問題:

給定數列a和b,問(i

(

i

滿足ai

<=aj

,bi<=bj

a

i<=aj

,b

i<=bj

的組數

我們把每乙個i對應的ai

,bi ai,

bi

當做二維平面上的點

並以x座標為比較函式進行排序,使得對於任意

i<

j i

<

j,滿足ai

<=aj

a

i<=aj

,這樣我們只需要討論b的情況,但是暴力跑一遍顯然是不夠優秀的

採用分治思想

將區間[l,

r][ l,

r]

分成[l

,mid

] [l,

mid]

和[mid+1

,r] [mi

d+1,

r]

,先遞迴處理子問題,再考慮當前情況下左區間對右區間的貢獻有多少

把左右區間按照b的值排序,這個時候左區間所有點的a嚴格小於等於右區間所有數的a,所以我們可以直接雙指標計算一下貢獻

每一層的時間效率都是o(

n)o (n

),一共有log層,於是時間複雜度是o(

nlog

n)o (n

logn

)思考一下如果是三維的情況怎麼辦?

我們先對x排序,然後我們發現這樣的問題轉化成了二維問題,然後就可以套用二維偏序的方法了

bzoj3262

#include

using

namespace

std;

#define n 100010

#define k 200010

struct bit

return ans;

}}t;struct nodep[n];

int n,k,ans[n];

inline

bool cmp1(node a,node b)

int mid=(l+r)>>1;

solve(l,mid);

solve(mid+1,r);

sort(p+l,p+mid+1,cmp2);

sort(p+mid+1,p+r+1,cmp2);

int tl=l,tr=mid+1;

while(tr<=r)

for(int i=l;iint main()

swap(n,newn);

solve(1,n);

memset(ans,0,sizeof(ans));

for(int i=1;i<=n;i++)ans[p[i].ans]+=p[i].cnt;

for(int i=1;i<=newn;i++)printf("%d\n",ans[i]);

return

0;}

但是如果增加了修改怎麼辦?

這是時cdq分治就變成了真·cdq分治

我們同樣可以把問題遞迴並且只考慮當前增層的狀態

但是我們發現了修改這一神奇物質

所以我們先很自然不可抗力地把原問題按照時間排序,。。。其實就是不動

然後我們解決了時間的限制之後就可以在原問題上進行遞迴了

思路大概是這樣的:

我們先將問題遞迴到左右子區間,分別統計之後我們只需要統計左區間修改對右區間查詢的貢獻(為什麼沒有右區間到左區間呢?),然後我們將左區間的修改和右區間的查詢全部拿出來(感性理解一下),然後我們發現這個時候修改和查詢又混在一起了,但是我們不用考慮時間關係只用考慮位置關係,所以我們就可以直接按照某一維的位置關係排乙個序。。。

然後我們就發現我們將原問題成功的降維了

感覺賊優秀

hdu5126

本人部落格

/*hdu5126 cdq分治*/

#include

#include

#include

#include

#include

using

namespace

std;

#define n 500010

struct bit

}t;struct que

que(int _x,int _y,int _z,int _id,int _typ,int _w)

}q1[n<<3],q2[n<<3],q3[n<<3],q4[n<<3];

int n,t,pre[n<<1],ans[n];

vector

v;bool cmp1(que a,que b)

for(int i=1;i1);

}void solve1(int l,int r)

int main()else

}sort(pre+1,pre+tot+1);

tot=unique(pre+1,pre+tot+1)-pre-1;

for(int i=1;i<=cnt;i++)q1[i].z=lower_bound(pre+1,pre+tot+1,q1[i].z)-pre;

solve1(1,cnt);//***cnt!=n

for(int i=0;iprintf("%d\n",ans[v[i]]);

}return

0;}

降維演算法之維度的概念

維度有一維,二維直到多維,人類能夠觸及到的最大維度只有三維。不同情形下,維度代表的意義也不相同。型別含義 陣列 series 維度就是功能shape返回的結果,shape中返回了幾個數字就是幾維 圖形 graphic 維度是影象中特徵向量的數量 對於陣列來說,維度就是功能shape返回的結果,sha...

降維演算法 t SNE和UMAP的python實現

from sklearn import manifold t sne 傾向於儲存區域性特徵,訓練較慢 for i in range listlength my value i np.array my value i reshape 1,64 tsne manifold.tsne n componen...

基於深度特徵對齊的資料降維演算法

基於ldfa的無監督資料降維 受ltsa啟發,本文提出一種基於深度學習框架的無監督降維演算法 related work 1.深度學習方法 有監督的學習方法 cnn 卷積神經網路 無監督的學習方法 aes 自動編碼器 2.區域性保持 流形學習的特點 由三個框架可知 不同的流形學習演算法有不同的區域性保...