AtCoder Regular Contest 145
#
#
过于简单,略
#
虽然简单但是细节特别多,略
#
题意:
给你一个数 ,我们定义一个长度为 的排列 的得分如下
将这个排列分成两个长度均为 的(不一定要连续的)子序列 以及 ,那么所有 的划分中 就是该排列的得分
令 表示所有排列的最大得分,求有多少种排列的得分为
答案对 取模
思路
显然对于四个数 满足 的情况,必然有 是两两乘积求和中最大的
那么这个长度为 的序列中的数就可以一一对应起来:
我们首先确定每一对数 把谁放在 序列中,也就是当作左边的元素
这样就一共有 种左边元素的方案
然后左边元素又可以任意排列,所以一共就有 中排列方式
然后我们再来考虑把它们放在排列 中
显然如果我们从左到右遍历一遍 ,那么左边元素的数量一定大于右边元素的数量
这不就是括号序列吗,括号序列的总方案数共有 种 (卡特兰数)
(我貌似还没有学会卡特兰数)
那么把它们乘起来,最后总方案数就是
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;
}
#
题意:
给定
要求构造出一个满足以下条件的集合
-
中有恰好 个数
-
中的所有数都在 之内
-
对于所有 都有
-
思路:
我们先只关注限制
那么有一种较好的构造方式是让集合 中的所有数三进制下均为
这样 的话 必然至少有一位为
并且 必然全是 ,这样就使得
然后我们再来考虑让所有数和为
我们先建立一个如上的集合 ,设集合
现在我们就是要把 变成 ,由于给集合 中所有数加上同一个数仍会满足限制
而集合中总共有 个数,我们每次全部数都减去一个 就相当于总共减去
所以我们需要做的就是把 变成 的倍数
也就是要把 减去
考虑我们可以把集合中的每一个数 ,这样我们就可以通过给 个数减去 来使得 减去 ,同时还能满足限制
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);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现