ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AtCoder Regular Contest 145

2022-07-31 14:32:14  阅读:189  来源: 互联网

标签:AtCoder 145 int text sum le Regular 2n bmod


\(\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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有