2025.3.3 总结

比赛链接

T1

思路

简单 dp。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5;
int n,a[N],b[N],c[N],f[N][3];
signed main()
{
	cin.tie(0)->sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;++i) cin>>a[i]>>b[i]>>c[i];
	f[1][0]=a[1],f[1][1]=b[1],f[1][2]=c[1];
	for(int i=2;i<=n;++i)
	{
		f[i][0]=max(f[i-1][1],f[i-1][2])+a[i];
		f[i][1]=max(f[i-1][0],f[i-1][2])+b[i];
		f[i][2]=max(f[i-1][0],f[i-1][1])+c[i];
	}
	cout<<max(f[n][0],max(f[n][1],f[n][2]));
	return 0;
}

T2

思路

先写出暴力转移的 dp,然后使用前缀和优化即可。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=105,M=1e5+5,mod=1e9+7;
int n,m,a[N],f[N][M],sum[N][M];
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;++i) cin>>a[i];
	f[0][0]=1;
	for(int i=1;i<=n;++i)
	{
		sum[i][0]=f[i-1][0];
		for(int j=1;j<=m;++j)
		{
			sum[i][j]=(sum[i][j-1]+f[i-1][j])%mod;
		}
		for(int j=0;j<=m;++j)
		{
			if(j-a[i]<1) f[i][j]=(sum[i][j]+mod)%mod;
			else f[i][j]=(sum[i][j]-sum[i][j-a[i]-1]+mod)%mod;
		}
	}
	cout<<f[n][m];
	return 0;
}

T3

思路

KMP 可以直接秒,但是太麻烦了。

我们直接记录前缀修改后长度与后缀修改后长度就完了,答案就是 \(\max(l_i + r_{i + 1})\)

代码

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,m,l[N],r[N];
string s,t;
int main()
{
	cin.tie(0)->sync_with_stdio(false);
	cin>>n>>m>>s>>t;
	s=' '+s,t=' '+t;
	for(int i=1;i<=n;++i) l[i]=l[i-1]+(s[i]==t[l[i-1]+1]);
	for(int i=n;i>=1;--i) r[i]=r[i+1]+(s[i]==t[m-r[i+1]]);
	int mx=0;
	for(int i=0;i<=n;++i) mx=max(mx,l[i]+r[i+1]);
	cout<<mx;
	return 0;
}

T4

思路

暴力很好写。

我们可以利用并查集来判断。

既然是要删边,但是不好实现,那么,就把删边操作改为不加这条边,如果将时间轴倒过来,就是如果要删边,就加边,这题就很好写了。

代码

#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
const int N=4e5+5;
int n,m,q,x[N],y[N],c[N],fa[N],a[N],siz[N];
string s[N];
bool vis[N];
int find(int x) {return (fa[x]==x?x:fa[x]=find(fa[x]));}
signed main()
{
	cin.tie(0)->sync_with_stdio(false);
	cin>>n>>m>>q;
	for(int i=1;i<=m;++i) cin>>x[i]>>y[i];
	for(int i=1;i<=q;++i) 
	{
		cin>>s[i];
		if(s[i]=="DELETE")
		{
			cin>>c[i];
			vis[c[i]]=1;
		}
	}
	for(int i=1;i<=n;++i)
	{
		cin>>a[i];
		fa[i]=i;
		siz[i]=a[i];
	}
	for(int i=1;i<=m;++i)
	{
		if(!vis[i])
		{
			int u=find(x[i]),v=find(y[i]);
			if(u==v) continue;
			if(v>u) swap(u,v);
			siz[v]+=siz[u],fa[u]=v;
		}
	}
	int sum=q+1,ans=siz[1]*(q+1);
	for(int i=q;i>=1;--i)
	{
		if(s[i]=="DELETE")
		{
			int u=find(x[c[i]]),v=find(y[c[i]]);
			if(u==v) continue;
			if(v>u) swap(u,v);
			if(v==1) ans+=sum*siz[u];
			siz[v]+=siz[u],fa[u]=v;
		}
		else sum=i;
	}
	for(int i=1;i<=n;++i)
	{
		if(find(i)!=1) ans+=a[i]*sum;
	}
	cout<<ans;
	return 0;
}
posted @ 2025-03-09 18:11  BUMIE  阅读(30)  评论(0)    收藏  举报