CDQ分治

地山發表於2024-12-10

CDQ分治,解決三維數點(三維偏序)問題。
第一維用分治化掉,用第一維<=mid的向第一維>mid的貢獻,剩下的兩維用二維數點解決。模板
線上二維數點轉化為離線三位數點
其實任何線上k維數點都可以轉化為離線(k+1)維數點,常見是把時間變成一維,每次數時間這一維比自己小且滿足另兩位限制的點(例1例2
CDQ最佳化DP
CDQ最佳化DP,就是當DP方程式要滿足一個三位偏序關係才能轉移時,可用CDQ處理。每次樹狀陣列修改時修改值維當前對應dp值。要注意必須左右CDQ中間夾著處理,像這樣:

點選檢視程式碼
 CDQ1(l,mid,lo);
    for(auto i:vp){
        if(h[i]<=mid)modify(v[i],f1[i]);
        else {
            f1[i]=Max(f1[i],query(v[i])+1);
            f1[i].cnt=max(f1[i].cnt,1.0);
        }
    }
    for(auto i:vp)if(h[i]<=mid)clear_(v[i]);
    CDQ1(mid+1,r,ro);
而不能這樣:
點選檢視程式碼
 CDQ1(l,mid,lo);CDQ1(mid+1,r,ro);
    for(auto i:vp){
        if(h[i]<=mid)modify(v[i],f1[i]);
        else {
            f1[i]=Max(f1[i],query(v[i])+1);
            f1[i].cnt=max(f1[i].cnt,1.0);
        }
    }
    for(auto i:vp)if(h[i]<=mid)clear_(v[i]);
    

四位偏序
其實就是在CDQ外面再套一層分治,把多出的一維幹掉(模板

相關文章