其他分享
首页 > 其他分享> > AtCoder Regular Contest 145

AtCoder Regular Contest 145

作者:互联网

\(\text{AtCoder Regular Contest 145}\)

目录

\(\text A\)

过于简单,略


\(\text B\)

虽然简单但是细节特别多,略


\(\text C\)

题意

给你一个数 \(n\),我们定义一个长度为 \(2n\) 的排列 \(\text P\) 的得分如下

将这个排列分成两个长度均为 \(n\) 的(不一定要连续的)子序列 \(\text A_{1\sim n}\) 以及 \(\text B_{1\sim n}\),那么所有 \(\text A,\text B\) 的划分中 \(\max\{\sum_{i=1}^n \text A_i\text B_i\}\) 就是该排列的得分

令 \(\text M\) 表示所有排列的最大得分,求有多少种排列的得分为 \(\text M\)

答案对 \(998244353\) 取模

\(1\le n\le 2\times 10^5\)

思路

显然对于四个数 \(\text{A,B,C,D}\) 满足 \(\text{A<B<C<D}\) 的情况,必然有 \(\text{AB+CD}\) 是两两乘积求和中最大的

那么这个长度为 \(2n\) 的序列中的数就可以一一对应起来:\(2n\to 2n-1,2n-2\to 2n-3,\cdots,2\to 1\)

我们首先确定每一对数 \((a,b)\) 把谁放在 \(\text A\) 序列中,也就是当作左边的元素

这样就一共有 \(2^n\) 种左边元素的方案

然后左边元素又可以任意排列,所以一共就有 \(n!\) 中排列方式

然后我们再来考虑把它们放在排列 \(\text P\) 中

显然如果我们从左到右遍历一遍 \(\text P\),那么左边元素的数量一定大于右边元素的数量

这不就是括号序列吗,括号序列的总方案数共有 \(\frac 1{n+1}\begin{pmatrix}2n\\n\end{pmatrix}\) 种 (卡特兰数)

(我貌似还没有学会卡特兰数)

那么把它们乘起来,最后总方案数就是

\[2^n\cdot n!\cdot \frac 1{n+1}\begin{pmatrix}2n\\n\end{pmatrix}=2^n\cdot \frac{2n!}{(n+1)!} \]

code

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

#define int long long
const int mod=998244353;

int n;

inline int qpow(int x,int idx){
	if(!idx) return 1;
	int t=qpow(x,idx>>1);
	return (idx&1)?t*t%mod*x%mod:t*t%mod;
}

signed main(){
	cin>>n;
	int ans=qpow(2,n);
	for(int i=n+2;i<=2*n;++i) ans=(ans*i)%mod;
	cout<<ans<<endl;
}

\(\text D\)

题意

给定 \(n,m\)

要求构造出一个满足以下条件的集合 \(\text S\)

\(1\le n\le 10^4,|m|\le n\times 10^6\)

思路

我们先只关注限制 \(3\)

\(y-x\ne z-y\to 2y\ne x+z\)

那么有一种较好的构造方式是让集合 \(\text S\) 中的所有数三进制下均为 \(0/1\)

这样 \(x<z\) 的话 \((x+z)_{(3)}\) 必然至少有一位为 \(1\)

并且 \(2y_{(3)}\) 必然全是 \(0/2\),这样就使得 \(2y\ne x+z\)

然后我们再来考虑让所有数和为 \(m\)

我们先建立一个如上的集合 \(\text S\),设集合 \(\sum_{s\in \text S}=sum\)

现在我们就是要把 \(sum\) 变成 \(m\),由于给集合 \(\text S\) 中所有数加上同一个数仍会满足限制 \(3\)

而集合中总共有 \(n\) 个数,我们每次全部数都减去一个 \(x\) 就相当于总共减去 \(nx\)

所以我们需要做的就是把 \(sum-m\) 变成 \(n\) 的倍数

也就是要把 \(sum\) 减去 \(((sum-m)\bmod n+n)\bmod n\)

考虑我们可以把集合中的每一个数 \(\times 3\),这样我们就可以通过给 \(((sum-m)\bmod n+n)\bmod n\) 个数减去 \(1\) 来使得 \(sum\) 减去 \(((sum-m)\bmod n+n)\bmod n\),同时还能满足限制 \(3\)

code


		for(int j=0;j<15;++j,tmp*=3){
			if((i>>j)&1)
				x+=tmp;
		}
		sum+=x;
		s[++cnt]=x;
	}
	int x=((m-sum)%n+n)%n;
	for(int i=1;i<=x;++i) ++s[i],++sum;
	//if(m<sum) for(int i=1;i<=n;++i)
	int delta=(sum-m)/n;
	for(int i=1;i<=cnt;++i)
		printf("%d ",s[i]-delta);
}

标签:AtCoder,145,int,text,sum,le,Regular,2n,bmod
来源: https://www.cnblogs.com/into-qwq/p/16537063.html