如果乙個區間的端點在區間內,則這個區間可以走到那個區間,詢問乙個區間能否到另乙個區間。
首先我們立馬想到了:如果兩個區間嚴格有交集,那麼這兩個區間所能到達的區間集合是一樣的。那麼如果兩個區間嚴格有交集的話我們就可以把它們合併起來,這裡運用並查集。
這樣處理完之後,剩下的區間只有兩種情況:包含或者相離。那麼查詢的時候顯然只要判斷兩個區間指向的大區間的情況即可。
最後,由於這題區間端點權比較大,所以要先離散化。
1 #include2 #includeview code3 #include4 #include5 #include6 #include7 #include8 #include9
using
namespace
std;
1011
const
int one=100005*8;12
const
int inf=1e9+1;13
14int
n;15
intnum,cnt;
1617 vector node[one];
1819
struct
power
20a[one],interval[one];
2324
intq[one],li_num;
25struct
lisan
26li[one];
2930
intget
()31
4041
namespace
li42
5051
int cmp(const lisan &a,const lisan &b)
52void
lisan()
5363 num=cnt;
6465 cnt=0;66
for(int i=1;i<=n;i++)
67if(a[i].opt==1
)68 a[i].l=q[++cnt], a[i].r=q[++cnt];
6970}71
}7273int
fat[one];
74int find(int
x)75
7980
namespace
seg81
93node[i].clear();94}
95if(l==r) return;96
int mid = (l+r)>>1;97
if(l <= mid) delete(i<<1
, l, mid, l);
98else delete(i<<1|1, mid+1
, r, l);99}
100101
void update(int i,int l,int r,int l,int
r)102
109int mid=(l+r)>>1
;110
if(l<=mid) update(i<<1
,l,mid,l,r);
111if(mid+1
<=r) update(i<<1|1,mid+1
,r,l,r);
112}
113}
114115
bool
p_edge(power a,power b)
116120
121int
main()
122130
for(int i=1;i<=num;i++) fat[i]=i;
131132
li::lisan();
133134 cnt=0
;135
for(int i=1;i<=n;i++)
136144
else
145152
}153 }
bzoj 4515 遊戲 樹鏈剖分 線段樹
先讓我 一發lych大佬點我去看dalao的題解 講的很詳細.這裡糾正乙個地方,lych大佬的式子中有乙個 a d s d x b a d x b a d s 應該是 a d s d x b a d x b a d s 看來是大爺敲式子的時候敲錯了.除去這個就很完美啦 新get了線段樹標記永久化的姿...
bzoj4881 線段遊戲
相當於走出兩條路線,將所有數包含,使得每條路線都是單調增的。為了方便我們加入p 0 0和p n 1 n 1。設f i 表示一條路線 沒有指定是第一條路線 走到了i 1,另一條路線走到了i,滿足條件的方案數。邊界是f 1 1,答案是f n 1 2 兩條路線實際上不可區分但原題中可區分那麼它們可以交換即...
BZOJ 4756 線段樹合併(線段樹)
思路 1.最裸的線段樹合併 2.我們可以觀察到子樹求乙個東西 那我們直接dfs序好了 入隊的時候統計一下有多少比他大的 出的時候統計一下 減一下 搞定 線段樹合併 by siriusren include include include using namespace std const int n...