題意:支援操作:
按順序在數軸上插入一條線段,刪除並詢問所有與這條線段有交的線段個數。
詢問當前數軸上一共有多少條線段。
想做了很久的題=。=
觀察到和線段\([l_i,r_i]\)有交的線段,實際上就是右端點\(\ge l_i\)並且左端點\(\le r_i\) 的一些線段。我們可以把所有線段按照右端點第一關鍵字,左端點第二關鍵字放進乙個treap裡。然後每次查詢當前插入的這條線段的後繼,即第乙個右端點\(\ge l_i\)的線段。如果它們有交,就刪掉這個線段,然後繼續判斷,否則\(break\)掉就行了。
似乎可以線段樹染色做?
#include#include#include#include#include#include#include#include#includeusing std::min;
using std::max;
using std::swap;
typedef double db;
const int n=200005;
typedef long long ll;
#define pb(a) push_back(a)
#define pii std::pair#define mp(a,b) std::make_pair(a,b)
int l[n],r[n];
int n,tot,root;
int ch[n][2],sze[n];
int prio[n],val[n],id[n];
void pushup(int cur)
void rotate(int &cur,int d)
void insert(int &cur,int x,int idx) sze[cur]++;
int d=val[cur]insert(ch[cur][d],x,idx);
if(prio[ch[cur][d]]}void remove(int &cur,int x,int idx) if(prio[ch[cur][0]]rotate(cur,0),remove(ch[cur][1],x,idx);
else rotate(cur,1),remove(ch[cur][0],x,idx);
pushup(cur);return;
}int d=val[cur]remove(ch[cur][d],x,idx);
pushup(cur);
}const int inf=0x3f3f3f3f;
int nxt(int cur,int x)
int getint()
signed main()
insert(root,r[i],i);
printf("%d\n",tot);
} else
printf("%d\n",sze[root]);
} return 0;
}
SHOI2009 會場預約
首先我們要知道,滿足什麼性質的線段,才與當前這個插入的線段有交集呢?那就是 線段的左端點在 1,r 但是線段的右端點大於l,所以,我們直接把線段的左端點當成下標,值當成r,插入到線段樹當中即可。然後刪除操作 只要在區間 1,r 並且區間max大於等於當前插入的線段的左端點,那麼就去刪除即可。同時線段...
SHOI2009 會場預約
orz 據說這個題有四種寫法 我孔乙己表示只會一種。暫時的 pp大廈有一間空的禮堂,可以為企業或者單位提供會議場地。這些會議中的大多數都需要連續幾天的時間 個別的可能只需要一天 不過場地只有乙個,所以不同的會議的時間申請不能夠衝突。也就是說,前乙個會議的結束日期必須在後乙個會議的開始日期之前。所以,...
SHOI2009 會場預約 線段樹
pp大廈有一間空的禮堂,可以為企業或者單位提供會議場地。這些會議中的大多數都需要連續幾天的時間 個別的可能只需要一天 不過場地只有乙個,所以不同的會議的時間申請不能夠衝突。也就是說,前乙個會議的結束日期必須在後乙個會議的開始日期之前。所以,如果要接受乙個新的場地預約申請,就必須拒絕掉與這個申請相衝突...