2024.3.30【比赛】高一下二调

唐氏比赛之板子比赛。写这篇博客的目的是为了凑博客数。

T1 交通管制

天乃蝶之家,地乃蝶之灵,云乃蝶之裳,花乃蝶之魂。

思路很显然,记录最短的路径,对于每一条边 \(\times 2\) 然后跑一次最短路,求最大的那个就行。

题面是简洁的,思路是清晰的,细节处理的是到位的,正确性是显然的,样例是能过的,代码是不想写的。

T2 教室安排

转笔,藏锋,护尾,横鳞。

最小距离最大化,很明显考虑二分。结束。

代陛下为耳目,书世间之万象。
#include <bits/stdc++.h>
#define N 100005

using namespace std;

int n,m,x[N],ans;

bool check(int mid){
	int res = x[1],num = 1;
	for(int i = 2;i <= n;i ++){
		if(x[i] - res >= mid) 
			num ++,res = x[i];
	}
	return num >= m; 
}

int main(){
	freopen("classroom.in","r",stdin);
	freopen("classroom.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i = 1;i <= n;i ++) scanf("%d",&x[i]);
	sort(x + 1,x + n + 1);
	int l = 1,r = 1000000000;
	while(l <= r){
		int mid = l + r >> 1;
		if(check(mid)) ans = mid,l = mid + 1;
		else r = mid - 1;
	}
	printf("%d",ans);
	return 0;
}

T3 招商

落在纸上的谎言,可以涂改过去,不能注定未来。

单调栈是真的忘了,没看出来是单调栈。看出来了也想不起来咋写。算是复习一次单调栈了。

思路是对于每一个 \(h_i\) 求助最小的 \(h_j\le h_i,j>i\)\(j\) 和最大的 \(h_k\le h_i,k<i\)\(k\),然后就求面积,最后取最大值即可。

身为女子,最快意的,莫过于持手中笔,量天下事。
#include <bits/stdc++.h>
#define N 400005
#define int long long

using namespace std;

int n,h[N],f[N],a[N],cnt,num,dp[N];

signed main(){
	freopen("post.in","r",stdin);
	freopen("post.out","w",stdout);
	scanf("%lld",&n);
	for(int i = 1;i <= n;i ++) scanf("%lld",&h[i]);
	for(int i = n;i >= 1;i --){
		while(cnt and h[a[cnt]] >= h[i]) cnt --;
		f[i] = cnt == 0 ? n + 1 : a[cnt];
		a[++cnt] = i;
	}cnt = 0;
	for(int i = 1;i <= n;i ++){
		while(cnt and h[a[cnt]] >= h[i]) cnt --;
		dp[i] = cnt == 0 ? 0 : a[cnt];
		a[++cnt] = i;
	}
	for(int i = 1;i <= n;i ++) num = max(num,h[i] * (f[i] - dp[i] - 1));
	printf("%lld",num);
	return 0;
} 

T4 帝国大会

盛世之风景将镌刻于笔墨,传颂于千秋。

思路显然。预处理出每一个节点到根节点的距离,求出最近公公祖先后,答案即为 \(a\)\(b\) 到根节点的距离和减去二倍祖先到根节点的距离之和。

依次写下名字,就成为家谱,就成为记忆,亲人们就在记忆中不朽。
#include <bits/stdc++.h>
#define N 100005
#define int long long

using namespace std;

int T,n,m,siz[N],dep[N],fa[N],top[N],son[N],dis[N];

struct Edge{int next,to,dis;}edge[N << 1];
int head[N],cnt;
void add(int from,int to,int dis){
	edge[++cnt] = (Edge){head[from],to,dis};
	head[from] = cnt;
}

void dfs1(int x,int f,int deep){
	siz[x] = 1,dep[x] = deep,fa[x] = f;
	int maxnson = -1;
	for(int i = head[x];i;i = edge[i].next){
		int y = edge[i].to;if(y == fa[x]) continue;
		dis[y] = dis[x] + edge[i].dis;
		dfs1(y,x,deep + 1);siz[x] += siz[y];
		if(siz[y] > maxnson) maxnson = siz[y],son[x] = y;
	}
}

void dfs2(int x,int f){
	top[x] = f;
	if(son[x]) dfs2(son[x],f);
	for(int i = head[x];i;i = edge[i].next){
		int y = edge[i].to;
		if(y == fa[x] or y == son[x]) continue;
		dfs2(y,y);
	}
}

void Input(){
	scanf("%lld%lld",&n,&m);
	for(int i = 1,u,v,w;i <= m;i ++){
		scanf("%lld%lld%lld",&u,&v,&w);
		add(u,v,w),add(v,u,w);
	}
	dfs1(1,0,1),dfs2(1,1);
//	for(int i = 1;i <= n;i ++) cout << dis[i] << " ";puts("");
}

int Find(int x,int y){
	while(top[x] != top[y]){
		if(dep[top[x]] < dep[top[y]]) swap(x,y);
		x = fa[top[x]];
	}
	return dep[x] > dep[y] ? y : x;
}

void work(){
	int x,y;scanf("%lld",&T);while(T --){
		scanf("%lld%lld",&x,&y);int l = Find(x,y);
		printf("%lld\n",dis[x] + dis[y] - 2 * dis[l]);
	}
}

signed main(){
	freopen("meeting.in","r",stdin);
	freopen("meeting.out","w",stdout);
	Input();work();return 0;
}
posted @ 2024-03-31 11:55  Joy_Dream_Glory  阅读(30)  评论(0编辑  收藏  举报