此次共五道題,前兩道水題不再多講(雖說後面3道也就普及左右難度233)
先是較簡單的t4,本題題意是,給定一棵最多 10000 個結點的樹,以及最多 100000 個詢問。對於每個詢問中要查詢的兩個結點,輸出它們之間路徑上的中點;特別地,如果這個中點在某條邊上,則輸出這條邊的兩個端點。注意這裡說的路徑是簡單路徑,也就是不能經過重複的邊和點。
於是思路很明顯了
1:找lca,進而找到兩點間距離,len=dep[x]+dep[y]-2*dep[lca(x,y)]
2:我們設計乙個 up(x,len)函式,用來計算從 x 向上跳不超過 len 的距離最多能到達的中點。然後分情況處理:
(1)如果 len 是偶數,則只有乙個中點。通過函式 up 從 x 或 y 中深度大的點盡量往上跳(不超過 len 步),找到最上面的乙個中點並輸出;
(2)如果 len 是奇數,則有兩個中點,通過函式 up 從 x 或 y 中深度大的點盡量往上跳(不超過 len 步),找到最上面的乙個中點並輸出它和它父親(共兩個點);
最後來分析以上演算法的複雜度。
(1)時間複雜度:預處理 f 陣列需要 o(nlog2n)的時間,每個查詢需要 o(log2n)的復
雜度,故整個演算法的時間複雜為 o((n+m)log2n)。
(2)空間複雜度:儲存 f 陣列需要 o(nlog2n)的空間,存放其他資訊需要 o(n)的空間,因此空間複雜度為 o(nlog2n)。
**
#include
using
namespace std;
const
int n=
10005
;int n,q,x,y;
int next[n*2]
,first[n*2]
,to[n*2]
,tot=0;
int f[n][15
],dep[n]
;//2^14=16384
void
add(
int u,
int v)
//建鄰接表
void
init
(int u,
int father)
//預處理,father 是 u 的父節點
}int
lca(
int x,
int y)
//找 lca
for(
int i=
14;i>=
0;i--
)//在 x 和 y 深度相同的情況下
}return f[x][0
];//最後肯定一起跳到了 lca 的下面乙個
}int
dist
(int x,
int y)
//求 x 和 y 的距離
intup
(int x,
int len)
//計算從 x 向上跳不超過 len 的距離最多能到達的中點
return x;
}void
ans(
int x,
int y)
//計算並輸出 x 和 y 的中點
}else}}
intmain()
init(1
,0);
//預處理(1 是根,0 是根的父親)
scanf
("%d"
,&q)
;for
(int i=
1;i<=q;i++
)return0;
}
然後t5,一道二分圖最大匹配模板題
傳送門容易想到的是將某個物品的兩個屬性分成左右部點,但是發現很難解決本題,尤其是在處理乙個物品只能用一種屬性的時候。
所以我們不妨換一種思路,對於物品 i 的屬性 a 和 b,分別從 a 和 b 向 i 連一條有向邊。將物品的屬性當做左部點,編號當做右部點,求最大匹配可。
這樣為什麼是正確的呢?我們可以考慮匈牙利演算法的具體過程:在匹配值為 的技能時,那麼 1~(i-1)的屬性肯定已經匹配完成,所以如果 i 對應的編號 j被匹配了的話,那麼就讓匹配 j 的那個屬性 p 再去找別的物品標號匹配,形象地說,就是用別的物品來釋放攻擊力為 p 的這個技能,用 j 這個物品釋放攻擊力為 i 的技能。如果找到這樣一條增廣路,那麼就說明當前可以匹配ans++。
平常我們將 vis 初值清零,訪問到這個點的時候就令 vis=1,而我們可以令在第 i 次匹配的時候就令 vis=i,這樣所有 vis 不是 i 的點就是沒有訪問過的,這樣就大大節省了時間複雜度。
**
#include
using
namespace std;
int n,x,y,t,whe[
1000001
],ans,match[
1000001
],first[
1000001
],to[
4000001
],next[
4000001
],tot;
void
add(
int a,
int b)
bool
dfs(
int x)}}
return
false;}
intmain()
for(
int i=
1;i<=
10000
;i++
) cout
}
t3純屬是考思維了,反正我沒想出來
就貼個**吧
傳送門
#include
using
namespace std;
int min[
1000001
],max[
1000001
],n,ans,tot;
struct dian
;dian a[
100001];
bool
comp
(dian i,dian j)
intmain()
sort
(a+1
,a+1
+n,comp)
; min[1]
=a[1
].y;
for(
int i=
2;i<=n;i++
) max[n]
=a[n]
.y;for
(int i=n-
1;i>=
1;i--
) ans=1;
for(
int i=
1;i<=n;i++
) cout
}
8月7日NOiP訓練
今天教練叫做了3道atcoderarc90上的題啊,1,2題倒是蠻水的,第3題,呵呵 t1傳送門 一道最基礎的dp,不過貌似這資料暴力也輕鬆過?include using namespace std int n,f 3 110 a 3 110 intread while isdigit ch ret...
2023年4月11日 4月13日訓練總結
今天的18浙江省在的題做的感覺不真實,分析一下吧。今天我的狀態還算不錯,有些題巧解出來了,很迷,因為都不是什麼 方面的知識,感覺都是思維題,甚至還有一道只要你讀懂題,就能ac的,感覺很不真實,今天的成績,說一下我們的問題,我們用了三颱電腦,這是不對的,但是還是感覺克制不住,但今天這樣的狀態我們以後就...
2023年4月18日 4月20日訓練總結
說說省賽之前的這幾次比賽吧。今天這次的狀態很差很差,昨天的那場比賽因為自己要上課,沒能陪他們一起打,隊友們還是很給力,做了四道,我就下了晚自習回來就看了一道題,手氣很好的抽到了一道好題,沒能做出來,後來的半個小時,集體討論了一下這道題結果還是沒出來,個人問題,脾氣比較倔,看了一道題總是想做出來,不願...