30
3030
分暴力送溫暖,但其實正解就從這裡拓展出來。
最本質的想法無疑是優化純模擬,先分析操作會對列隊帶來的變化。首先出去上廁所的人從它這一行刪除,行末從最後一行補乙個人。最後一行也對應的刪除那個人,並且加入上廁所的人,都是刪除並從後面加入。
顯然線段樹模擬刪除操作,加入的人用vector
\text
vector
存著,但是線段樹的空間貌似開不下,這個時候就需要動態開點了。對於每一次刪除操作,如果沒有這棵子樹,那就新增這棵子樹,每次最多開 logn
\log_n
logn
層,空間複雜度就壓縮到了 q
log
nq\log_n
qlogn
。
#include
#pragma gcc optimize(3)
#define for(i,x,y) for(int i=(x),i##end=(y);i<=i##end;++i)
#define dor(i,x,y) for(int i=(x),i##end=(y);i>=i##end;--i)
typedef
long
long ll;
using
namespace std;
const
int n=
3e5+3;
const
int nlogn=
6e6+3;
struct node
;struct segmenttree
void
create
(int
&k,int sum);}
intquery
(int x,
int y,
int n)
intquery
(int
&k,int l,
int r,
int k)
}st;
vectorh[n]
;int n,m,q;
intmain()
else tmp=las;
h[0]
.push_back
(tmp)
;printf
("%lld\n"
,tmp);}
return0;
}
NOIP2017 列隊(樹狀陣列)
定義第i行為所有的點 i,j 0 可以發現,每一行是相對獨立的,每一次操作只會影響到當前行和最後一列 考慮每一行和最後一列各開乙個樹狀陣列,但這樣顯然會爆空間 實際上,對於沒有離隊過的點是沒必要儲存的,可以直接算出編號,因此只要用vector儲存每一行和最後一列後加入的點即可 還需要預處理乙個陣列d...
Noip2017Day2練習題總結
本來很有信心,連題面昨天都沒沒看,結果全炸了。乳酪 dfs忘記標記回溯。初始化還犯了多麼智障的錯 自己都要笑哭 memset x,0,sizeof x memset x,0,sizeof y memset x,0,sizeof z memset x,0,sizeof mark 寶藏 void dfs...
NOIp2017D2T3 列隊(線段樹)
sylvia是乙個熱愛學習的女 孩子。前段時間,sylvia參加了學校的軍訓。眾所周知,軍訓的時候需要站方陣。sylvia 所在的方陣中有 n mn times mn m 名學生,方陣的行數為 nnn 列數為 mmm 為了便於管理,教官在訓練開始時,按照從前到後,從左到右的順序給方陣中 的學生從 1...