AtCoder Regular Contest 145
作者:互联网
\(\text{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\)
-
\(\text S\) 中有恰好 \(n\) 个数
-
\(\text S\) 中的所有数都在 \([-10^7,10^7]\) 之内
-
对于所有 \(\ x,y,z(x<y<z)\) 都有 \(y-x\ne z-y\)
-
\(\sum_{s\in \text S}=m\)
\(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