分治,考慮前一半對後一半的影響。
(和一般分治不太相同的思想是,一般分治不分誰對誰的影響,跨mid的都要統計。(全域性變數統計)
而cdq貌似要落腳到前一半對後一半的影響上,也就是貢獻在後一半統計,由前一半產生。
)大概使用情況:
1.三維偏序
2.優化dp
3.???
這個裡面有。
注意處理三維情況的巧妙性。
[heoi2016/tjoi2016]序列
cdq三維偏序優化dp
(樹套樹也沒問題)
注意的是,先divi(l,mid)再統計(l,r)再遞迴divi(mid+1,r)
因為必須統計貢獻有先後了。否則顯然有後效性。。
[boi2007]mokia 摩基亞
矩陣查詢,字首差分。
然後cdq分治,兩邊按照x排序一下,然後雙指標掃瞄,左半部分的修改,加入權值線段樹(權值樹狀陣列)裡,然後區間查詢統計增加的使用者即可。
可以離散化節省時空。
#include#define reg register intmokia 摩基亞#define il inline
#define mid ((l+r)>>1)
#define numb (ch^'0')
using
namespace
std;
typedef
long
long
ll;il
void rd(int &x)
namespace
miraclet[
4*n];
struct
que}q[n];
inttot;
struct
matrixa[
10000+5
];int
cnt;
intb[n],c[n],num;
intmx;
void pushup(int
x)void add(int x,int l,int r,int to,int
c)
if(to<=mid) add(x<<1
,l,mid,to,c);
else add(x<<1|1,mid+1
,r,to,c);
pushup(x);
}int query(int x,int l,int r,int l,int
r)
int ret=0
;
if(l<=mid) ret+=query(x<<1
,l,mid,l,r);
if(mid1|1,mid+1
,r,l,r);
return
ret;
}void divi(int l,int
r) add(
1,1,num,q[j].y0,q[j].sum);
++j;
}q[i].sum+=query(1,1
,num,q[i].y0,q[i].y1);
}for(reg i=l;ii)
//for(reg i=1;i<=tot;++i)
//cout<
intmain()
else
if(op==1
)
else
}sort(b+1,b+num+1
); num=unique(b+1,b+num+1)-b-1
;
//cout<
else
}divi(
1,tot);
for(reg i=1;i<=tot;++i)
else
if(q[i].typ==3
) }
for(reg i=1;i<=cnt;++i)
return0;
}}intmain()
/*author: *miracle*
date: 2018/11/23 21:10:32
*/
學習筆記 CDQ分治
聽娜姐講完fft,一臉懵逼,還是來講講 cdq分治 吧。解決 帶時間軸的更改和查詢 問題。首先我們要知道,這個演算法是離線的,還是利用遞迴進行求解的。把讀入的n個操作都按照時間軸排列好。把時間軸劈開,分為 l,mid 和 mid 1,r 兩部分。開始當前層cdq l,r 的求解前先進行cdq l,m...
CDQ分治學習筆記
今天學了一下cdq分治,感覺這東西真的挺好用的,趕緊寫點東西怕以後再忘咯 其實類似於cdq分治的東西在oi早期學排序的時候就應該學過,那就是歸併排序 歸併排序的原理和cdq分治大體一樣,先劃分成兩個區間,遞迴解決兩邊,再合併起來 並且用歸併排序求逆序對的時候本質上就是在解決乙個二維偏序的問題 首先回...
CDQ分治 學習筆記
對於每個 查詢 操作,其結果ans i 1,i 1 ans i 1,i 1 ans i 1,i 1 中所有修改對其造成影響的疊加 這裡的 疊加 需要能夠比較方便的維護,例如sum min max sum min max sum mi n ma x等 定義s ol ve l r solve l,r s...