考試總結 小奇模擬賽

2022-04-16 21:37:46 字數 4228 閱讀 3953

給定一棵 \(n\) 個節點的樹,求前 \(m\) 條最長路徑的長度。

序號 \(n\)

\(m\) 資料型別

1 10 3 暴力

2 233 23333 暴力

3 2000 300000 暴力

4 2000 300000 暴力

5 50000 1 隨機生成

6 7798 17798 隨機生成

7 7798 27798 隨機生成

8 7798 37798 隨機生成

9 50000 300000 1-n 順序輸入的鏈

10 50000 300000 以 1 為根的菊花圖

估分:\(70\)

實測:\(40\)

因為寫鏈時腦子抽了居然用了 \(map\) 然後空間炸了,還有判斷是否是鏈那裡寫錯了一點導致第乙個點還掛了。。。

對於鏈:先把 \(1-i(i <= n)\) 的所有鏈加入堆,然後取出最大的輸出,再把這條鏈刪掉上面那條邊,扔進堆裡

對於菊花圖:把每條邊排個序,可以構造乙個矩形,矩形的 \((x, y)\) 代表的是 \(d[x] + d[y]\) ,\(d[i]\) 是 \(i\) 到 \(1\) 的邊權,先把第一行全部扔進堆裡,取最大的輸出,再把 \((x + 1, y)\) 上的值扔進去

對於暴力:列舉每條鏈,用 \(lca\) 維護鏈的長度

正解:點分治,把每棵子樹做超級鋼琴的做法,用 \(st\) 表或者線段樹維護

不知道如何下手...照著網上的一篇題解打的

#include#define f(i, x, y) for(int i = x; i <= y; ++i)

using namespace std;

int read();

const int n = 5e4 + 5;

int n, m;

int sum, root, mx, id, l, r;

int head[n], cnt, ver[n << 1], edge[n << 1], nxt[n << 1];

int st[n * 20][21], d[n * 20], size[n], vis[n], dis[n];

struct nodep[n * 20];

struct use;

priority_queueq;

bool operator<(use a,use b)

void add(int x, int y, int z)

void get_root(int x, int fa)

maxn = max(maxn, sum - size[x]);

if(maxn < mx) mx = maxn, root = x;

}void dfs(int x, int fa)

; for(int i = head[x]; i; i = nxt[i])

if(! vis[ver[i]] && ver[i] != fa)

dis[ver[i]] = dis[x] + edge[i], dfs(ver[i], x);

}void solve(int x)

, l = r = id;

for(int i = head[x]; i; i = nxt[i])

if(! vis[ver[i]])

dis[ver[i]] = edge[i], dfs(ver[i], x), r = id;

for(int i = head[x]; i; i = nxt[i])

if(! vis[ver[i]])

root = 0, sum = size[ver[i]], mx = int_max, get_root(ver[i], 0), solve(root);

}int query(int l, int r)

void pre());}

int main()

); if(k.r - k.mq) q.push(use);

} return 0;

}int read()

while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();

return x * f;

}

給定 \(n\) 個點(編號為 \(1-n\)),由 \(m\) 條無向邊連線的圖,每個點有兩個權值 \(ax\),\(bx\),給定乙個值 \(k\),要求在圖中選出大小為 \(k\) 的點集 \(s\),使 \(s\) 中任意兩點間存在僅經過在 \(s\) 中的點的路徑。

設 \(as\) 為點集 \(s\) 中 \(ax\) 的最大值,\(bs\) 為 \(s\) 中 \(bx\) 的最大值,求乙個合法的 \(s\) 使得 \(as+bs\) 最小。

原本打了乙個暴力的結果只有 \(12pts\)

\(/kk\)

正解:星球上有 \(n\) 個城市,標號為 \(1-n\),用 \(n-1\) 條雙向通道連線,保證任意兩個城市能互相到達。

生化危機爆發了!但由於**安全能力有限,安全區只包括在標號 \(l\) 到 \(r\) 的城市,你現在在城市 \(x\),想知道最近的安全城市的距離。

對於 \(30\%\) 的資料, \(n,q<=1000\);

另有 \(20\%\) 的資料,保證第城市 \(2-n\) 均可直接到達城市 \(1\);

另有 \(10\%\) 的資料,保證城市 i(1<=i<=n-1)可直接到達城市 \(i+1\);

對於 \(100\%\) 的資料, \(n,q<=100000\),\(li<=ri\),任意兩個城市的距離小於 \(10^9\)。

估分:\(60\)

實測:\(60\)

對於鏈:如果在 \([l \ ,\ r]\) 裡輸出 \(0\),不在則取 \(min(d[x][l] \ , \ d[x][r])\),\(d[i][j]\) 表示 \(i \ , \ j\) 之間距離

對於菊花圖:用 \(st\) 表維護 \(l-r\) 的每個點到 \(1\) 的路徑的 \(min\) 值,分情況討論即可

對於其他:直接 \(dfs\) ,加個剪枝,當當前距離大於 \(ans\) 時返回,可以水過此題

正解:要用到點分治還是點分樹來著,我分不太清這兩個,大概就是,拆成很多個子樹,在每個子樹上都做乙個動態加點線段樹,維護此子樹里在 \(l-r\) 中的點到子樹根的最小值,用此最小值加上子樹根到 \(x\) 的值,更新 \(ans\),然後再往上跳,找新的子樹根

(正解只存在於口胡233

#include#define ll long long

#define f(i, x, y) for(int i = x; i <= y; ++i)

using namespace std;

ll read();

const int n = 1e6 + 5;

const int m = n << 1;

const ll inf = 1e18 + 5;

int n, q, flag;

ll x, y, z, l, r, ans;

ll head[n], cnt, ver[m], nxt[m];

ll edge[m], d[n], st[n][22], ok[n];

void add(ll x, ll y, ll z)

void dfs1(int x, int fa)

void solve_1()// 鏈

exit(0);

}void solve_2()// 菊花圖

exit(0);

}void dfs3(ll x, ll fa, ll dis)

for(int i = head[x]; i; i = nxt[i])

if(ver[i] != fa)

dfs3(ver[i], x, dis + edge[i]);

}void solve_3()// 其他

} int main()

q = read();

if(! flag) solve_1();

f(i, 2, n) if(ver[head[i]] != 1) flag = 0;

if(flag) solve_2();

solve_3();

return 0;

}ll read()

while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();

return x * f;

}

NOIP模擬賽考試總結

noip模擬賽考試總結 這兩天我們進行了以小奇為主題的noip模擬賽 考試總結 第一題看出是乙個dp,但是前面的決策對後面有影響,百思不得其解時想到後面決策對前面沒有影響,所以從後面開始dp,每步取max。第二題看了半天都不會,交了乙個暴力演算法,得了0分,因為我把字首和取模了,比如 1 2 3 4...

2019 11 12 CSP模擬賽 考前小總結

離聯賽只有幾天了,也馬上就要回歸文化課了。有點捨不得,感覺自己的水平剛剛有點起色,卻又要被抓回文化課教室了,真想在機房再賴幾天啊。像19 11 11那場的簡單題,自己還是能敲出一些比較穩的暴力,雖然不見得能拿很高檔的暴力或者打出正解,但至少不會掛分,最後能拿到的分數也還能看。但是一上點難度,或者不對...

20151006模擬賽總結

今天上午去一中,又考了個模擬賽。這次的題有點考思維。我感覺這個第一題難度稍微大了點。一般noip第一題要麼是簡單的模擬,要麼是裸的簡單演算法,這次的第一題要自己構造演算法,並且還是列舉和貪心套在一起。我開始想的是列舉 揹包,複雜度為n 3,但是資料範圍沒給出三次方的分。於是我就覺得不靠譜。然後發現列...