人,只有自己站起来,这个世界才能属于他。|

园龄:粉丝:关注:

2025 USACO Feb 银组题解合集

A

考虑从大到小考虑每一个取值的数,如果能换就换,如果换了没用就不换。

实现上使用 vector 存下标,复杂度 O(n)

#include<bits/stdc++.h>
using namespace std;
int t,n,m,a[1000005],flag,tim;
vector<int> v[1000005],ans,out;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			v[a[i]].push_back(i);
		}
		ans.push_back(0);
		ans.push_back(0);
		m=ans.size();
		for(int i=n;i>=1;i--){
			if(!v[i].size()) continue;
			flag=false;
			for(int j=0;j<v[i].size();j++){
				if(v[i][j]<ans[m-1] && v[i][j]>ans[m-2]) flag=true;
			}
			if(flag && !tim){
				tim=1;
				ans[m-1]=ans[m-2];
			}
			for(int j=0;j<v[i].size();j++){
				if(v[i][j]>ans[m-1]) ans.push_back(v[i][j]),out.push_back(i);
			}
			m=ans.size();
		}
		cout<<out[0];
		for(int i=1;i<out.size();i++){
			cout<<' '<<out[i];
		}
		tim=m=0;
		out.clear();
		ans.clear();
		for(int i=1;i<=n;i++){
			v[i].clear();
		}
		if(t) cout<<'\n';
	}
	return 0;
}

B

考虑建出树,然后倒序考虑每一个叶子。每次询问时,暴力跳父亲并标记节点,这个叶子的答案就是最后一个没有被标记的祖先的深度。

实现上 dfs 即可,复杂度 O(n)

#include<bits/stdc++.h>
using namespace std;
int n,m,x,cnt[1000005],w[1000005],ans[1000005];
int head[1000005],nxt[2000005],target[2000005],tot;
void add(int x,int y){
	tot++;
	nxt[tot]=head[x];
	head[x]=tot;
	target[tot]=y;
}
int dep[1000005],vis[1000005],f[1000005];
void dfs(int x,int fa){
	for(int i=head[x];i;i=nxt[i]){
		int y=target[i];
		if(y==fa) continue;
		f[y]=x;
		dep[y]=dep[x]+1;
		dfs(y,x);
	}
}
int find(int x){
	while(!vis[f[x]] && x){
		vis[x]=1;
		x=f[x];
	}
	vis[x]=1;
	return dep[x];
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>x;
		add(x,i);
		cnt[x]++;
		cnt[i]++;
	}
	for(int i=1;i<=n;i++){
		if(cnt[i]==1) m++;
	}
	for(int i=1;i<=m;i++){
		cin>>w[i];
	}
	dfs(0,0);
	for(int i=m;i>=1;i--){
		ans[i]=find(w[i]);
	}
	for(int i=1;i<=m;i++){
		cout<<ans[i]<<'\n';
	}
	return 0;
}

C

注意到如果从最终状态往前推,每次能够进行的操作是唯一的。

然后瓶颈在于加快这个模拟过程。

不难发现,在大部分情况下,(a,b)(amodb,b)

然后就可以每次判断能否这么做,直接搜索即可。

复杂度 O(logv)

#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,a,b,c,d;
int solve(int a,int b,int c,int d,int val){
	if(!a || !b || a<c || b<d) return -1;
	if(a<b) swap(a,b),swap(c,d);
	if(b==d && a%b==c%b) return val+(a-c)/b;
	else return solve(a%b,b,c,d,val+a/b);
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>t;
	while(t--){
		cin>>c>>d>>a>>b;
		cout<<solve(a,b,c,d,0)<<'\n';
	} 
	return 0;
}

本文作者:Kenma

本文链接:https://www.cnblogs.com/Kenma/p/18731262

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   _Kenma  阅读(80)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起