莫隊演算法學習記錄

2021-09-22 18:37:01 字數 4493 閱讀 1037

可以去這裡找我掛的題,第二第三道要硬拿莫隊做,有點難,不建議寫。

以下為學習記錄:

昨天補了一道非常接近莫隊思維的題

可以看看我這篇部落格e題然後再來看莫隊就好理解了:

(之前貼錯鏈結了。。。已更)

例題:cf 617e:

題解:a. n的1e5和m的1e5通過莫隊來實現

b. 字首異或

**:

#include

using

namespace std;

#define ll long long

#define forn(i,n) for(int i=0;i#define for1(i,n) for(int i=1;i<=n;i++)

#define io ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)

const

int maxn =

1e5+5;

int a[maxn]

,pos[maxn]

,cnt[

1<<21]

;ll ans[maxn]

;struct nodeq[maxn]

;bool

cmp(node a,node b)

intmain()

forn

(i,m)

sort

(q,q+m,cmp)

;int l=

1,r =0;

cnt[0]

=1; ll res =0;

forn

(i,m)

while

(l>q[i]

.l)while

(r>q[i]

.r)while

(l.l) ans[q[i]

.id]

= res;

}forn

(i,m) cout <<<

'\n'

;return0;

}

2019ccpc湘潭站 c題 hdu-6534

莫隊+樹狀陣列(這題卡常–線段樹會t)

很容易看出來是莫隊題。

題目求l,r內相減絕對值小於k,那麼我們可以離散化每個點 v,v+k,v-k然後用樹狀陣列維護出現的次數

#include

using

namespace std;

#define ll long long

#define forn(i,n) for(int i=0;i#define for1(i,n) for(int i=1;i<=n;i++)

#define io ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)

const

int maxn =

27005

;int n,m,k,z;

struct aa[maxn]

;vector<

int>b;

struct qq[maxn]

;ll ans[maxn]

;bool

cmp(q a,q b)

struct bit

;inline

intlb

(int x)

;void

update

(int pos,

int v)

;int

ask(

int pos)

;inline

intquery

(int l,

int r)

;}bit;

void

hash()

}int

main()

z =sqrt

(n);

forn

(i,m)

sort

(q,q+m,cmp)

;hash()

; ll res =0;

int l =

1,r =0;

forn

(i,m)

forn

(i,m) cout<<<

'\n'

;return0;

}

回滾莫隊bzoj4241

回滾的話好像只有一篇題解講得比較好,大致意思是指,莫隊排完序之後,在同一塊內,右指標是排好序的,當遇到一種情況,我們只能新增不能刪除比如維護最大值,就得利用這個性質,每次右指標移動,記錄狀態,然後左指標移動記錄答案然後再回到上次的狀態即可,這個複雜度還是n根號n的,如果在同一塊中就暴力根號n即可

**:

#include

using

namespace std;

#define ll long long

#define forn(i,n) for(int i = 0;i#define for1(i,n) for(int i=1;i<=n;i++)

#define io ios::sync_with_stdio(false);cin.tie(0)

const

int maxn =

1e5+5;

vector<

int>b;

int a[maxn]

,num[maxn]

,num2[maxn]

,pos[maxn]

,has[maxn]

,n,m;

ll ans[maxn]

;struct qq[maxn]

;bool

cmp(q a,q b)

voidha(

)}intmain()

forn

(i,m)ha(

);sort

(q,q+m,cmp)

; ll res =

0,res2 =0;

bool ok =1;

int l =

(pos[q[0]

.l]+1)

*z,r =l-

1,l2 = l;

forn

(i,m)}if

(pos[q[i]

.l]==pos[q[i]

.r])

for(

int j = q[i]

.l;j<=q[i]

.r;j++)}

else

ans[q[i]

.id]

= res;

}forn

(i,m) cout<<<

'\n'

;return0;

}

帶修改莫隊,貌似分塊n^2/3更快。

bzoj2120

#include

using

namespace std;

#define ll long long

#define forn(i,n) for(int i = 0;i#define for1(i,n) for(int i =1;i<=n;i++)

#define io ios::sync_with_stdio(false);cin.tie(0)

const

int maxn =

1e5+5;

const

int maxm =

1e6+5;

int a[maxn]

,num[maxm]

,pos[maxn]

,vis[maxn]

,ans[maxn]

,pre[maxn]

,res;

struct qq[maxn]

;struct cc[

1005];

bool

cmp(q a,q b)

return pos[a.l]

void

cal(

int p)

else

vis[p]^=

1;}void

change

(int p,

int v)

else a[p]

= v;

}int

main()

int cntq =

0,cntc =0;

forn

(i,m)

; cntq++;}

else

; pre[x]

= y;}}

sort

(q,q+cntq,cmp)

;int l =

1,r =0;

for(

int j =

1;j<=q[0]

.tim;j++

)change

(c[j]

.p,c[j]

.v);

forn

(i,cntq)

forn

(i,cntq) cout<<<

'\n'

;return0;

}

莫隊演算法學習筆記

莫隊演算法 有時候我們經常會碰到這樣一類問題 給定n和n個數etc,然後給出m組區間詢問 l,r 要求對所有詢問區間給出答案。然後發現這類題通常有乙個很好的性質就是,如果你知道了 l,r 的答案,就可以o 1 或者o lgn 再大就有點玄了 的知道 使得根據第i個區間 li,ri 的答案拓展到第i ...

莫隊演算法學習報告

一直聽說這個神奇的 據說能解決所有區間問題的演算法 今天學習了一下,可能我只做了幾個模板題,覺得不是很難。我覺得這個寫的挺好的 點我 莫隊演算法說起來也是暴力,只不過利用了分塊的思想優雅的把n 2變成了n 1.5,太強了,orz。用乙個小栗子解釋一下分塊的思想 有一棟樓有100層高,給你兩個雞蛋,讓...

莫隊演算法學習筆記(一) 普通莫隊

前言 在學習莫隊演算法之前,我一直以為這是乙個很高深的演算法。實際上,它就是乙個很高深的演算法 這個演算法玄學地將分塊與暴力兩大演算法實現了二合一,從而打造出了乙個時間複雜度為o n n o n sqrt n o nn 的求解多個區間詢問的離線演算法。具體介紹 首先,我們以詢問中l ll所在的區間為...