AtCoder Beginner Contest 399 (abc399) 赛后复盘

当前 A-D + F

A&B

简单题,不多赘述。

A
#include<bits/stdc++.h>

#define pii pair<int,int> 
#define pll pair<long long,long long> 
#define ll long long
#define i128 __int128

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define in4(a,b,c,d) a=read(), b=read(), c=read(), d=read()
#define fst first 
#define scd second 
#define dbg puts("IAKIOI")

using namespace std;

int read() {
	int x=0,f=1; char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); 
	for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }

const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }

#define maxn 200050

int n;
string s,t;

void work() {
	cin>>n>>s>>t;
	int ans=0;
	For(i,0,n-1) if(s[i]!=t[i]) ans++;
	cout<<ans<<'\n';
}

signed main() {
//	freopen("data.in","r",stdin);
//	freopen("myans.out","w",stdout);
//	ios::sync_with_stdio(false); 
//	cin.tie(0); cout.tie(0);
	double stt=clock();
	int _=1;
//	_=read();
//	cin>>_;
	For(i,1,_) {
		work();
	}
	cerr<<"\nTotal Time is:"<<(clock()-stt)*1.0/1000<<" second(s)."<<'\n';
	return 0;
}
B
#include<bits/stdc++.h>

#define pii pair<int,int> 
#define pll pair<long long,long long> 
#define ll long long
#define i128 __int128

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define in4(a,b,c,d) a=read(), b=read(), c=read(), d=read()
#define fst first 
#define scd second 
#define dbg puts("IAKIOI")

using namespace std;

int read() {
	int x=0,f=1; char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); 
	for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }

const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }

#define maxn 200050

int n;
pii p[maxn];
int rk[maxn];
bool cmp(pii a,pii b) {
	return a.first!=b.first?a.first>b.first:a.second>b.second;
}

void work() {
	in1(n);
	For(i,1,n) in1(p[i].first),p[i].second=i;
	sort(p+1,p+n+1,cmp);
	For(i,1,n) if(p[i].first==p[i-1].first) rk[p[i].second]=rk[p[i-1].second];
		else rk[p[i].second]=i;
	For(i,1,n) cout<<rk[i]<<'\n';
}

signed main() {
//	freopen("data.in","r",stdin);
//	freopen("myans.out","w",stdout);
//	ios::sync_with_stdio(false); 
//	cin.tie(0); cout.tie(0);
	double stt=clock();
	int _=1;
//	_=read();
//	cin>>_;
	For(i,1,_) {
		work();
	}
	cerr<<"\nTotal Time is:"<<(clock()-stt)*1.0/1000<<" second(s)."<<'\n';
	return 0;
}

C

一棵树是由 \(n\) 个点 \(n-1\) 条边组成的,我们先找出图中的所有连通块,发现大小为 \(x\) 的连通块实际上只需要 \(x-1\) 条边,剩下的都是不需要的。统计一下答案即可。

点击查看代码
#include<bits/stdc++.h>

#define pii pair<int,int> 
#define pll pair<long long,long long> 
#define ll long long
#define i128 __int128

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define in4(a,b,c,d) a=read(), b=read(), c=read(), d=read()
#define fst first 
#define scd second 
#define dbg puts("IAKIOI")

using namespace std;

int read() {
	int x=0,f=1; char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); 
	for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }

const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }

#define maxn 200050

int n,m;
vector<int> G[maxn];
bool vis[maxn];
int bel[maxn], bcnt;
int cnt[maxn];

void dfs(int u,int fa) {
	bel[u]=bcnt; cnt[bcnt]--; vis[u]=1;
	for(auto v:G[u]) if(v!=fa&&!vis[v]) {
		dfs(v,u);
	}
}
int a[maxn],b[maxn];

void work() {
	in2(n,m);
	For(i,1,m) {
		int u,v;
		in2(u,v);
		a[i]=u,b[i]=v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	For(i,1,n) if(!bel[i]) {
		bcnt++;
		dfs(i,-1);
	}
	For(i,1,m) {
		cnt[bel[a[i]]]++;
	}
	int res=0;
	For(i,1,bcnt) res+=cnt[i]+1;
	cout<<res<<'\n';
}

signed main() {
//	freopen("data.in","r",stdin);
//	freopen("myans.out","w",stdout);
//	ios::sync_with_stdio(false); 
//	cin.tie(0); cout.tie(0);
	double stt=clock();
	int _=1;
//	_=read();
//	cin>>_;
	For(i,1,_) {
		work();
	}
	cerr<<"\nTotal Time is:"<<(clock()-stt)*1.0/1000<<" second(s)."<<'\n';
	return 0;
}

D

一个二元组 \((a,b)\) 满足条件,当且仅当序列中没有相邻的 \(a\)\(b\) 元素时,有两对相邻的不重复的无序对 \((a,b)\)
所以我们只需要检查该元素两边的元素是否能构成一个二元组就好了。
我们记录序列中 \((a_i,a_{i-1})\) 出现的次数。对于答案统计,我们分类讨论:

  • \(a_{i-1}=a_{i+1}\) 时,至少有 \((a_{i-1},a_{i})>1\) 或者是 \((a_i,a_{i-1})>1\) 才满足要求。
  • 其他情况只需要加起来大于等于 \(2\) 即可。

时间复杂度 \(O(n\log n)\),用 map<pair<int,int>,int> 常数较大,但是 AtCoder 机子快,能过。

点击查看代码
#include<bits/stdc++.h>

#define pii pair<int,int> 
#define pll pair<long long,long long> 
#define ll long long
#define i128 __int128

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define in4(a,b,c,d) a=read(), b=read(), c=read(), d=read()
#define fst first 
#define scd second 
#define dbg puts("IAKIOI")

using namespace std;

int read() {
	int x=0,f=1; char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); 
	for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }

const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }

#define maxn 400050

int n,a[maxn];
bool vis[maxn];
int t_cnt[maxn];
ll ans=0;

void work() {
	ans=0;
	map<pii,int> mp,flg; mp.clear(),flg.clear();
	in1(n);
	For(i,1,n+n) {
		in1(a[i]);
		if(a[i-1]==a[i]) vis[a[i]]=1;
	}
	For(i,2,n+n) if(!vis[a[i-1]]&&!vis[a[i]]) mp[{a[i],a[i-1]}]++;
	For(i,2,n+n-1) if(a[i-1]==a[i+1]) flg[{a[i-1],a[i]}]=1;
	For(i,2,n+n) if(!vis[a[i]]&&!vis[a[i-1]]) {
		if(flg[{a[i-1],a[i]}]||flg[{a[i],a[i-1]}]) {
			if(mp[{a[i],a[i-1]}]>1||mp[{a[i-1],a[i]}]>1) {
				ans++,mp[{a[i],a[i-1]}]=0,mp[{a[i-1],a[i]}]=0;
	//			dbg;
//				cout<<a[i]<<' '<<a[i-1]<<'\n';
			}		
		} else {
			if(mp[{a[i],a[i-1]}]+mp[{a[i-1],a[i]}]>=2) {
				ans++,mp[{a[i],a[i-1]}]=0,mp[{a[i-1],a[i]}]=0;
			//	cout<<a[i]<<' '<<a[i-1]<<'\n';
			}		
		}		
	}
	cout<<ans<<'\n';
	For(i,1,n+n) vis[i]=0;
}

signed main() {
//	freopen("data.in","r",stdin);
//	freopen("myans.out","w",stdout);
//	ios::sync_with_stdio(false); 
//	cin.tie(0); cout.tie(0);
	double stt=clock();
	int _=1;
	_=read();
//	cin>>_;
	For(i,1,_) {
		work();
	}
	cerr<<"\nTotal Time is:"<<(clock()-stt)*1.0/1000<<" second(s)."<<'\n';
	return 0;
}
/*
1
4
1 2 3 2 4 3 4 1

*/

E

未完工。

F

我们看回题目所给的式子(\(s_i\) 表示 \(\sum_{j=1}^{i} a_j\)):

\[\sum_{l=1}^{n} \sum_{r=l}^{n} (s_r+(-s_{l-1}))^k \]

根据二项式定理:\((a+b)^k=\sum_{i=0}^{k}C_{k}^{i}a^{k-i}b^{i}\),我们可以把上面的式子换成这样:

\[\sum_{l=1}^{n}\sum_{r=l}^{n}\sum_{i=0}^{k}C_{k}^{i}{s_r}^{k-i}{(-s_{l-1})^{i}} \]

我们发现 \(\sum_{i=0}^{k}C_{k}^{i}{s_r}^{k-i}{(-s_{l-1})^{i}}\) 中,\(C_{k}^{i}{(-s_{l-1})^{i}}\) 并不受 \(r\) 取值的影响,所以我们可以把它提出来,变成下面这个样子:

\[\sum_{l=1}^{n}\sum_{i=0}^{k}C_{k}^{i}(-s_{l-1})^i\sum_{r=l}^{n}{s_r}^{k-i} \]

最后,我们发现我们可以预处理出来 \(\sum_{r=l}^{n}{s_r}^{k-i}\),那么就很好做了。时间复杂度 \(O(nk\log V)\),其中 \(V\)\(a_i\) 值域。

点击查看代码
#include<bits/stdc++.h>

#define int ll
#define pii pair<int,int> 
#define pll pair<long long,long long> 
#define ll long long
#define i128 __int128

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()
#define in4(a,b,c,d) a=read(), b=read(), c=read(), d=read()
#define fst first 
#define scd second 
#define dbg puts("IAKIOI")

using namespace std;

int read() {
	int x=0,f=1; char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); 
	for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }

const int mod = 998244353;
int qpo(int a,int b) {int res=1; a=(a%mod+mod)%mod; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }

#define maxn 200050

int n,k,a[maxn],s[maxn];
int sum[12][maxn];
int fac[maxn],ifac[maxn];
int C(int n,int m) {//n 选 m
	return fac[n]*ifac[n-m]%mod*ifac[m]%mod;
}

void work() {
	in2(n,k);
	fac[0]=1; ifac[0]=inv(fac[0]);
	For(i,1,k) fac[i]=fac[i-1]*i,ifac[i]=inv(fac[i]);
	For(i,1,n) in1(a[i]),s[i]=(s[i-1]+a[i])%mod;
	For(i,0,k) Rep(j,n,1) sum[i][j]=(sum[i][j+1]+qpo(s[j],i))%mod;
//	For(j,0,k) For(i,1,n) cout<<sum[j][i]<<(i==n?'\n':' ');
	int ans=0;
	For(i,1,n) {
		int res=0;
		For(j,0,k) {
			res+=qpo(-s[i-1],j)%mod*C(k,j)%mod*sum[k-j][i]%mod;
			res=(res%mod+mod)%mod;
		}
		ans+=res;
		ans=(ans%mod+mod)%mod;
	}
	cout<<ans<<'\n';
}

signed main() {
//	freopen("data.in","r",stdin);
//	freopen("myans.out","w",stdout);
//	ios::sync_with_stdio(false); 
//	cin.tie(0); cout.tie(0);
	double stt=clock();
	int _=1;
//	_=read();
//	cin>>_;
	For(i,1,_) {
		work();
	}
	cerr<<"\nTotal Time is:"<<(clock()-stt)*1.0/1000<<" second(s)."<<'\n';
	return 0;
}
posted @ 2025-03-30 00:27  coding_goat_qwq  阅读(136)  评论(0)    收藏  举报