可以去這裡找我掛的題,第二第三道要硬拿莫隊做,有點難,不建議寫。
以下為學習記錄:
昨天補了一道非常接近莫隊思維的題
可以看看我這篇部落格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所在的區間為...