目錄問題 b: 蜀傳之單刀赴會
問題 c: 吳傳之火燒連營
本篇題解也發表於zwcblog作者是同乙個人
眾所周知,劉備在長阪坡上與他的一眾將領各種開掛,硬生生從曹操手中逃了出去,隨後與孫權一**燒赤壁、占有荊益、成就霸業。而曹操則在赤壁一敗後再起不能,終生無力南下。
建安二十五年(220年),曹操已到風燭殘年,但仍難忘當年長阪的失誤,霸業的破滅。他想如果在劉備逃亡的路中事先布下一些陷阱,便能拖延劉備的逃脫時間了。你作為曹操身邊的太傅,有幸穿越到了208年的長阪坡,為大魏帝國貢獻乙份力,布置一些陷阱。但時空守衛者告訴你你不能改變歷史,不能拖增大劉備的最大逃脫時間,但你身為魏武之仕,忠心報國,希望能新增一些陷阱使得劉備不論怎麼逃跑所用的時間都一樣。
已知共有n個據點,n-1條棧道,保證據點聯通。1號據點為劉備軍逃跑的起點,當劉備軍跑到某個據點後不能再前進時視為劉備軍逃跑結束。在任意乙個棧道上放置1個陷阱會使通過它的時間+1,且你可以在任意乙個棧道上放置任意數量的陷阱。
現在問你在不改變劉備軍當前最大逃跑時間的前提下,需要新增最少陷阱,使得劉備軍的所有逃脫時間都盡量的大。
第一行乙個數n,表示據點個數。
接下來n-1行每行三個數,ai、bi、ti,表示從據點ai通過第i個棧道到bi耗時ti
僅包含乙個數,為需要新增的最少陷阱數。
3
1 2 1
1 3 3
2
對於 5%的資料,1<=n<=100000,1<=ti<=200000
對於 100%的資料,1<=n<=500000,0此題是一道樹形dp,很顯然,它就是讓你求 從根開始到每乙個葉子結點的權值和相等需要改多少邊權
設\(f[x]\)表示以\(x\)為跟,到它的子樹中權值的最大值
再設\(sum\)表示已\(x\)為根的權值總和
再設x為根的節點有\(cnt\)個孩子
則對於\(x\),答案要加上\(cnt*f[x]-sum\)
**如下(因為比較簡單,就不解釋了)
還有,記得開\(long\ long\)啊
#include #include using namespace std;
typedef long long ll;
const int n=1000005;
int n,edge;
ll ans;
int next[n],head[n],vet[n],val[n];
ll f[n];
inline void add(int u,int v,int va)
void dfs(int u,int father)
ans+=(1ll*max*cnt-sum);
f[u]=max;
}int main()\)
這是什麼意思呢??
如果關羽還沒有到過i,但他到過j,他就可以從j走到i
最後的答案就是\(f[sta][i]+dis[i][0]\)(若\(sta\)到過\(0\)號與\(k+1\)號且\(f[sta][i]+dis[i][0]<=d\))
及到過他自己的與魯肅的陣地中且最後再返回自己的陣地
上**:
#include #include #include #include using namespace std;
const int n=100005;
struct ac
inline void add(int u,int v,int va)
void dijkstra(int st));dis[st]=0;
while (!q.empty()));}}
}}int main()
friend[0]=1;friend[k+1]=n;//新增兩個朋友,及自己與魯肅
for (int i=1;i<=k;++i) read(friend[i]);
for (int i=0;i<=(k+1);++i)
} int n=1<0) //如果j屬於sta
dp[i][sta|(1<0&&(sta&(1<0)//判斷sta有多少1,及關羽拜訪了多少朋友
if (cnt>ans) else
if (cnt==ans) ans=min(ans,dis[i][0]+dp[i][sta]);}}
} }if (ans==2000000000) puts("-1"); else printf("%d %d\n",ans-2,ans);//判斷-1
return 0;
}
蜀漢章武元年(221年),劉備為報吳奪荊州、關羽被殺之仇,率大軍攻吳。吳將陸遜為避其鋒,堅守不戰,雙方成對峙之勢。蜀軍遠征,補給困難,又不能速戰速決,加上入夏以後天氣炎熱,以致銳氣漸失,士氣低落。劉備為舒緩軍士酷熱之苦,命蜀軍在山林中安營紮寨以避暑熱。陸遜看準時機,命士兵每人帶一把茅草,到達蜀軍營壘時邊放火邊猛攻。蜀軍營寨的木柵和周圍的林木為易燃之物,火勢迅速在各營漫延。蜀軍大亂,被吳軍連破四十餘營。陸遜火燒連營的成功,決定了夷陵之戰蜀敗吳勝的結果。
劉備帶兵深入吳境,陸遜卻避而不出,蜀軍只得在山林中安營紮寨。而劉備在紮營時卻犯了兵家大忌,將兵營排列成一條直線,遠遠看去,就像是一條串著珠子的鏈,美其名曰:鏈寨。如果吳軍將領是一般人,那麼這也許不算什麼,而陸遜何許人也,他可是江東才子,能力不低於周瑜的一代儒將。他看到劉備這樣排陣,心生一計,決定用火攻破陣。然而,火計除了要有風,選定引火點也非常重要,對於劉備的布陣,最佳引火點一定是n個兵營中的乙個。而因為風水輪流轉,每天的最佳引火點都不一樣。我們給每個兵營定下乙個固定不變的火攻值ai,每天定下乙個風水值k,對於每天的最佳引火點,顯然是所有兵營中火攻值與風水值異或的結果最大的那乙個兵營。然而,陸遜是個謹慎的人,他要觀察時機,在m天中選定乙個最佳的進攻的日期,為此他演算出了這m天每天的風水值,然後他希望你能夠告訴他這m天每天最佳引火點的兵營編號。
第一行n,m,代表有n個兵營,m天.
接下來一行有n個非負整數,代表這n個兵營的火攻值。
接下來一行有m個非負整數,代表這m天的風水值。
輸出共m行,每行輸出乙個整數,代表第m天最佳引火點的編號。
如果存在多個最佳引火點使得火攻值與風水值的異或值最小,請任意輸出一組解即可。
3 2
1 2 3
4 5
3
2
對於第1天,由於4 xor 1=5, 4 xor 2=6, 4 xor 3=7,選擇第3個引火點是最佳的。
對於第2天,由於5 xor 1=4, 5 xor 2=7, 5 xor 3=6,選擇第2個引火點是最佳的。
對於30%資料,n<=1000,m<=1000
對於100%資料,n<=100000,m<=100000, 0<=k,ai<=2147483647
其實這道題目就是一道trie樹模板題
trie樹我就不再贅述了,可以戳這裡
從\(2^->2^\)每次掃一遍即可
平均時間複雜度\(o(35n)\)
陣列一定要開大一點!!
**:
#include #include #include using namespace std;
int trie[8000000][2],m,a[100],b[8000000],root,tot,tot,n,x;
void read(int &a)
void build(int yyy)
b[root]=yyy;
}int ask()
return b[root];
}int main()
build(i);
} for (int i=1;i<=m;++i)
printf("%d\n",ask());
} return 0;
}
7 21模擬測試題解
用nlogn求出最長不下降子串行長度然後判長度是否有n 1就行了 因為每個數只能用一次,所以前i個數所能組成的最大和為a 1 a 2 a i 若a i 1 a 1 a 2 a i 1 則因為比a 1 a 2 a i 大的下乙個數必 a i 1 所以a 1 a 2 a i 1為答案。include i...
19 2 18 測試題解
題太水了懶得乙個乙個發 t1 題意就是5000000個點,10000000條邊,邊權只有1或2,求最短路 我的做法 先bb一句,要開始考試的時候l讓我和gigo,gsy去樓下考,我說看一下題再決定,然後他說 你看,第一題是裸的最短路。又因為我懶得搬東西去樓下並且不想承受爆零 墊底的壓力,於是就留在樓...
2019 8 5測試題解(NOIP2019模擬)
有一顆n nn個點的樹,每個點有乙個權值a aa,設其兒子個數為s ss,要滿足每個點的a s m a s le m a s m,求最多能刪多少個點 乙個點刪掉後,它的a加到父親上,所有兒子連到父親上 1 n 2000000,1 m 100000,0 ai 1000 1 le n le 200000...