hack 國的居民人人都是 oi 大師,hometown 得知便趕緊來到 hack 國學習。可想要進入 hack 國並不是件容易的事情,首先就必須通過 hack 國海關小 b 的考驗。小 b 覺得 hometown 比較菜,於是就扔了一道小水題給 hometown。
給定乙個長度為 n 的數列 a i ,接下來會對這個序列進行 m 次操作。操作型別分為以下兩種:
l r,表示將區間 [l,r] 輪轉一次,具體來說,a l ,a l+1 ,a l+2 ,··· ,a r−1 ,a r 經過一次輪轉之後,會變為 a r ,a l ,a l+1 ,··· ,a r−1 ;
l r k,詢問區間 [l,r] 內 ai = k 的個數。
可惜 hometown 還是不會做,他只能期待你能解決這個問題了。
n,m<=1e5
這很noip
注意到這個輪換操作非常的splay,我們可以用splay來維護這個操作
乙個暴力的做法就是分塊。我們預處理每個塊內的桶,每次輪換操作等價於從每個塊中取出最後乙個位置,加入下乙個塊中作為下一塊的第乙個位置。這個在splay上面求第k個即可
分析一波複雜度,無論是修改還是查詢都是n
nlogn
n\sqrt n\log n
nnlog
n的,實測跑不過暴力quq,說多了都是淚
冷靜分析一波可以發現我們這個splay沒有什麼用,注意到我們只需要資瓷求塊內的開始元素和結束元素,因此我們只需要維護n
\sqrt n
n個鍊錶即可,對於散塊直接暴力把鍊錶拉出來再重構
開了o2,各種stl直接上。
#include
#include
#include
#include
#include
#define rep(i,st,ed) for (register int i=st;i<=ed;++i)
#define drp(i,st,ed) for (register int i=st;i>=ed;--i)
const
int n=
100005
;int bel[n]
,st[n]
,ed[n]
;int b[
350]
[n],c[n]
;struct block
void
push_back
(int x)
intpop_front()
intpop_back()
void
move
(int l,
int r)
} q[
350]
;inline
intread()
intmain
(void
)for
(;m--;)
b[bel[r]
][tmp]++;
c[0]
=0;rep
(i,st[bel[r]
],r) c[
++c[0]
]=q[bel[r]].
pop_front()
; b[bel[r]
][c[c[0]
]]--;
drp(i,c[0]
-1,1
) q[bel[r]].
push_front
(c[i]);
q[bel[r]].
push_front
(tmp)
; tmp=c[c[0]
]; c[0]
=0;rep
(i,st[bel[l]
],l-
1) c[
++c[0]
]=q[bel[l]].
pop_front()
; b[bel[l]
][tmp]++;
q[bel[l]].
push_front
(tmp)
;drp
(i,c[0]
,1) q[bel[l]].
push_front
(c[i]);
}else q[bel[l]].
move
(l-(bel[l]-1
)*b,r-
(bel[l]-1
)*b);}
else
else
drp(i,c[0]
,1) q[bel[l]].
push_back
(c[i]);
c[0]
=0;rep
(i,st[bel[r]
],r)
drp(i,c[0]
,1) q[bel[r]].
push_front
(c[i]);
rep(i,bel[l]+1
,bel[r]-1
) ans+
=b[i]
[x];
}printf
("%d\n"
, ans);}
}return0;
}
JZOJ 二分 抄書
與書的複製差不多 洛谷 書的複製 但是只要輸出最大的時間 樣例輸入9 3 100 200 300 400 500 600 700 800 900樣例輸出1700樣例解釋1 1500 100 200 300 400 500 2 1300 600 700 3 1700 800 900 1300 1500...
二分 抄書 (jzoj 2123)
有n本書,分給m個人抄,每個人只能拿到連續的書 不能把一本書分開 問抄書最多的人要抄多少頁9 3 100 200 300 400 500 600 700 800 9001700對於10 的資料,有n 10 對於50 的資料,有n 500 對於100 的資料,有n 3000 這道題很可能想到dp但會炸...
暴力 二分答案 JZOJ 蛋糕
有乙個n m n mn m的蛋糕 有數字 橫著切三刀在豎著切三刀分成16份使最小的最大。首先 最小的最大 確定了這題可以二分答案 這題我們先暴枚豎切三刀,再二分判定 include include include using namespace std int n,m,rr,ans,l,r int ...