題目鏈結
最樸素的想法是將圖建出來跑最短路。
觀察後發現如下兩條性質:
1.邊權是1,可以用廣度優先搜尋代替最短路。
2.因為是廣度優先搜尋,每條邊只會被鬆弛一次。
但是圖的大小可能是n
2n^2
n2級別的。我們考慮使用線段樹維護隱式圖來支援搜尋。
複雜度o(n
log2
n)o(nlog_2n)
o(nlog
2n)
。
#include
#include
#include
#include
using
namespace std;
#define lson rt * 2
#define rson rt * 2 + 1
void
read
(int
&x)const
int n =
1e5+
100;
struct node
node
(int y,
int id):y
(y),
id(id)
}tree[n *4]
;bool
operator
<
(node a, node b)
bool
operator
>
(node a, node b)
int n, tp;
int sx[n]
, sy[n]
, ex[n]
, ey[n]
, dis[n]
, has[n]
;priority_queue
, greater
> p[n *4]
;queue<
int> q;
void
build
(int l,
int r,
int rt)
void
insert
(int id,
int l,
int r,
int rt)
int m =
(l + r)/2
;if(sx[id]
<= has[m]
)insert
(id, l, m, lson)
;else
insert
(id, m +
1, r, rson)
; tree[rt]
=min
(tree[lson]
, tree[rson]);
}void
query
(int id,
int l,
int r,
int rt)
if(p[rt]
.empty()
) tree[rt]
=node
(2e9,0
);else tree[rt]
= p[rt]
.top()
;return;}
int m =
(l + r)/2
;query
(id, l, m, lson);if
(ex[id]
>= has[m +1]
)query
(id, m +
1, r, rson)
; tree[rt]
=min
(tree[lson]
, tree[rson]);
}int
main()
sort
(has +
1, has + n +1)
; tp =
unique
(has +
1, has + n +1)
- has -1;
for(
int i =
1; i <= n; i++
)insert
(i,1
, tp,1)
; q.
push(0
);while
(!q.
empty()
)if(dis[n]==0
) dis[n]=-
1;printf
("%d\n"
, dis[n]);
return0;
}
卡牌遊戲II bfs
有n張卡片,上面印著整數a1,a2,a3 an,可以選取其中任意數量張卡片,求出乙個和s,共有2 n 1個和 要求出最小的前n個和分別是多少 題目包含多組資料。輸入的每一行有乙個整數t 1 t 5 代表有t組資料 對於每組資料分為兩行 第一行有兩個整數n,k 其中1 n 200000,1 k min...
卡牌遊戲期望
題目描述好像有點問題。應該是n種卡牌。m種稀有卡牌,且抽出不放回。對於求期望來說,相比之下我們更容易求出概率。而對於此類題目 期望往往 1 概率 暫時這麼理解的 而期望具有可加性。把所有稀有卡牌都抽一遍的期望 每次抽得乙個稀有卡牌的期望的和。至少抽出k張稀有卡牌的期望 抽出k張每次抽的乙個稀有卡牌的...
A 卡牌遊戲 III ACM
蒜頭君在玩一種卡牌遊戲,他有 n 張卡牌,每張卡牌上寫著兩個正整數 ai,bi ai 表示這張卡牌的能量值,bi表示這張卡牌的魔法值。蒜頭君要從這 n張卡牌中選出一些形成乙個卡組,用這個卡組對敵人造成傷害。乙個卡組對敵人的傷害是這個卡組中所有卡牌的能量值之和乘其中魔法值最小的一張卡牌的魔法值。蒜頭君...