The 2021 ICPC Asia Jinan Regional Contest

本文分别探讨了组合优化问题,利用动态规划求解最优策略;等差数列的处理,寻找使序列和最小的差值;行列式的计算,通过高斯消元法求解;以及图论中的搜索算法,计算节点的平均距离。这些内容涵盖了算法的基础与应用,对于提升算法能力具有重要意义。
摘要由CSDN通过智能技术生成

C Optimal Strategy

#include<bits/stdc++.h>
#define ll long long
using namespace std;

ll n, f[1000050];
ll cnt[1000050];
ll sum[1000050];

//--组合数学--
const int Cmod = 998244353;
ll fac[1000100],inv[1000100];
int power(int a,int b)
{
    int ret;
    if (b==0) return 1;
    ret=power(a,b/2);
    ret=1ll*ret*ret%Cmod;
    if (b%2)ret=1ll*ret*a%Cmod;
    return ret;
}
void pre(){
    fac[0]=1;inv[0]=1;
    for(int i=1;i<=1000000;i++)
	{
        fac[i]=1ll*fac[i-1]*i%Cmod;
        inv[i]=power(fac[i],Cmod-2);
    }
}
int C(int n,int m)
{
    if (n<m) return 0;
    if (n<0||m<0) return 0;
    return 1ll*fac[n]*inv[m]%Cmod*inv[n-m]%Cmod;
}
//----------
void solve()
{
	cin>>n;
	int x;
	for(int i=1;i<=n;i++) cin>>x, cnt[x]++;
	for(int i=1;i<=n;i++) sum[i] = sum[i-1] + cnt[i];
	bool flag = 0;
	for(int i=1;i<=n;i++)
	{
		if(!cnt[i])
		{
			f[i] = f[i-1];
			continue;
		}
		if(!flag)
		{
			flag = 1;
			f[i] = 1;
			for(int j=2;j<=cnt[i];j++) f[i] = (f[i] * j) %Cmod;
			continue;
		}
		f[i] = f[i-1] * C(sum[i-1]+cnt[i]/2, sum[i-1]) %Cmod;
		for(int j=2;j<=cnt[i];j++) f[i] = (f[i] * j) %Cmod;
	}
	cout<<f[n]<<endl;
}
int main()
{
	pre();
	solve();
}

D Arithmetic Sequence

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5+100;

ll n, a[N], b[N], ans;

__int128 check(__int128 d) {
	d -= 1e13;
	for(ll i=1; i<=n; i++) b[i] = a[i] + d * (n-i);

	nth_element(b+1, b+(n/2+1), b+1+n);
	ll haf = b[n/2+1];

	__int128 sum = 0;
	for(int i=1; i<=n; i++) {
		if(b[i] > haf)
			sum += b[i] - haf;
		else
			sum += haf - b[i];
	}
	if(ans > sum) ans = sum;
	return sum;
}
int main() {
	scanf("%lld", &n);
	for(int i=1; i<=n; i++) scanf("%lld", &a[i]);

	if(n==1) {
		printf("0");
		return 0;
	}

	ans = 5e18;
	ll l = 0, r = 2e13;
	while(l < r) {
		ll mid1 = (l*2+r)/3;
		ll mid2 = (l+r*2+2)/3;
		if(check(mid1) < check(mid2)) {
			r = mid2 - 1;
		} else l = mid1 + 1;
	}
	printf("%lld", ans);
	return 0;
}

J Determinant

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int mod = 1e9+7;
inline ll Qpow(ll a,ll b){ll s=1;while(b){if(b&1){s=(s*a)%mod;}a=a*a%mod;b>>=1;}return s;}
inline ll Qinv(ll a){return Qpow(a,mod-2);}

string det;
ll n, a[110][110];

ll gauss()
{
	ll ans = 1;
	for(int i=1;i<=n;i++)
	{
		for(int j=i;j<=n;j++)
		{
			if(a[j][i])
			{
				for(int k=i;k<=n;k++) swap(a[i][k], a[j][k]);
				if(i != j) ans = -ans;
				break;
			}
		}
		if(!a[i][i]) return 0;
		ll inv = Qinv(a[i][i]);
		for(int j=i+1;j<=n;j++)
		{
			int tmp = a[j][i] * inv %mod;
			for(int k=i;k<=n;k++) a[j][k] = (a[j][k] - tmp * a[i][k] %mod + mod) %mod;
		}
		ans = (ans * a[i][i] %mod + mod) %mod;
	}
	return ans;
}
void solve()
{
	cin>>n>>det;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
			cin>>a[i][j];
	}
	ll ans = gauss();
	
	ll res = 0;
	int len = det.size();
	for(int i=0;i<len;i++) res = (res*10 + det[i]-'0') %mod;
	
	if(ans == res) puts("+");
	else puts("-");
}
int main()
{
	int t; cin>>t;
	while(t--) solve();
}

K Search For Mafuyu

#include<bits/stdc++.h>
using namespace std;

vector<int> eg[110];
int vis[110], tim, n;

void dfs(int x, int far)
{
	vis[x] = ++tim;
	for(auto y:eg[x])
	{
		if(y!=far && vis[y]==0)
			dfs(y, x);
	}
	tim++;
}
void solve()
{
	cin>>n;
	int a, b;
	for(int i=1;i<=n;i++) eg[i].clear();
	for(int i=2;i<=n;i++)
	{
		cin>>a>>b;
		eg[a].push_back(b);
		eg[b].push_back(a);
	}
	tim = 0;
	for(int i=1;i<=n;i++) vis[i] = 0;
	dfs(1, -1);
	double ans = -n;
	for(int i=1;i<=n;i++) ans += vis[i];
	ans /= (n-1);
	printf("%.10lf\n", ans);
}
int main()
{
	int t; cin>>t;
	while(t--) solve();
}
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_45928596

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值