2022五一爆零记总结二
五一第三天 ,被关在学校不能出去玩QAQ
第一题结论推炸了,打表看到1、2、5该想到是卡特兰数的
第二题想到过分块但是觉得太麻烦于是就没有打诶嘿
第三题题目做法是推出来了的,容斥DFS写炸最后竟然还有20分
第一题 数列
题面在下面啦
点击查看题目
数列(sequence.c/cpp/pas)
1 题目描述
我们称一个长度为 2n 的数列是有趣的,当且仅当该数列满足以下三个条件:
(1)它是从 1 到 2n 共 2n 个整数的一个排列{ai};
(2)所有的奇数项满足 a1<a3<…<a2n-1,所有的偶数项满足 a2<a4<…<a2n;
(3)任意相邻的两项 a2i-1与 a2i(1≤i≤n)满足奇数项小于偶数项,即:a2i-1<a2i。
现在的任务是:对于给定的 n,请求出有多少个不同的长度为 2n 的有趣的数列。因为
最后的答案可能很大,所以只要求输出答案 mod P 的值。
2 输入格式
输入文件只包含用空格隔开的两个整数 n 和 P。
3 输出格式
仅含一个整数,表示不同的长度为 2n 的有趣的数列个数 mod P 的值。
4 样例输入
3 6
5 样例输出
5
6 数据范围与约定
对于 30%的数据满足 n≤1000;
对于另外 30%的数据满足 P 为质数;
对于 100%的数据满足 n≤1000000 且 P≤1000000000。
代码如下
点击查看代码
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int f=1,j=0;char w=getchar();
while(w>'9'||w<'0'){
if(w=='-')f=-1;
w=getchar();
}
while(w>='0'&&w<='9'){
j=(j<<3)+(j<<1)+w-'0';
w=getchar();
}
return f*j;
}
const int N=2000001;
bool use[N];
int zhi[N],f[N],tail,n,mod;
int sumi(int sum,int num){
long long ansn=1,nown=sum;
while(num>0){
if(num&1)ansn=ansn*nown%mod;
num/=2;
nown=nown*nown%mod;
}
return ansn;
}
signed main(){
//freopen("sequence.in","r",stdin);
//freopen("sequence.out","w",stdout);
n=read();mod=read();
for(int i=2;i<=n*2;i++){
if(!use[i])zhi[++tail]=i;
for(int u=1;u<=tail&&zhi[u]*i<=n*2;u++)use[zhi[u]*i]=true;
}
for(int i=1;i<=tail;i++){
for(int u=1;zhi[i]*u<=2*n;u++){
int a=zhi[i]*u;
if(zhi[i]*u<=n){
while(a%zhi[i]==0){
f[i]--;
a/=zhi[i];
}
}
if(zhi[i]*u>n+1){
while(a%zhi[i]==0){
f[i]++;
a/=zhi[i];
}
}
}
}
long long ans=1;
for(int i=1;i<=tail;i++){
if(f[i]==0)continue;
ans=ans*sumi(zhi[i],f[i])%mod;
}
printf("%d",ans);
return 0;
}
第二题 乘法
题面如下点击查看
点击查看代码
乘法 (mul.c/cpp/pas)
1 题目描述
输入一个 n ∗ n 的矩阵 A,请求出 A^1+A^2+...+A^k 对 m 取模的结果。
2 输入格式
第一行为三个正整数 n, k, m,含义如上所述;
接下来 n 行,每行输入 n 个非负整数,用于描述矩阵 A。
3 输出格式
输出 n 行,每行 n 个整数,表示答案矩阵。
4 样例输入
2 2 5
2 1
0 3
5 样例输出
1 1
0 2
6 数据范围与约定
对于前 30% 的数据,k<=30;
对于另外 30% 的数据,n=1;
对于 100%的数据,n<=30, k<=10^9, m<=10^4
4,输入矩阵的数在 0~m-1 范围内。
不得不说矩阵套矩阵然后推快速幂的方法真的是非常的妙啊...
代码如下
点击查看代码
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int f=1,j=0;char w=getchar();
while(w>'9'||w<'0'){
if(w=='-')f=-1;
w=getchar();
}
while(w>='0'&&w<='9'){
j=(j<<3)+(j<<1)+w-'0';
w=getchar();
}
return f*j;
}
const int N=31,M=32;
int n,k,mod;
struct matrix{
int s[N][N];
matrix operator *(const matrix &a)const{
matrix b;
for(int x=1;x<=n;x++){
for(int y=1;y<=n;y++){
long long ansn=0;
for(int i=1;i<=n;i++)ansn=(ansn+s[x][i]*a.s[i][y])%mod;
b.s[x][y]=ansn;
}
}
return b;
}
matrix operator +(const matrix &a)const{
matrix b;
for(int x=1;x<=n;x++){
for(int y=1;y<=n;y++){
b.s[x][y]=(s[x][y]+a.s[x][y])%mod;
}
}
return b;
}
}mid,yuan,kong;
struct node{
matrix line[2][2];
node operator *(const node &a)const{
node b;
for(int i=0;i<=1;i++){
for(int u=0;u<=1;u++){
b.line[i][u]=line[i][0]*a.line[0][u];
b.line[i][u]=b.line[i][u]+(line[i][1]*a.line[1][u]);
}
}
return b;
}
}sta;
node sumi(int tim){
node nown=sta,ansn;
ansn.line[0][0]=ansn.line[1][1]=yuan;
ansn.line[1][0]=ansn.line[0][1]=kong;
while(tim>0){
if(tim%2==1)ansn=ansn*nown;
tim/=2;
nown=nown*nown;
}
return ansn;
}
signed main(){
//freopen("mul.in","r",stdin);
//freopen("mul.out","w",stdout);
n=read();k=read();mod=read();
for(int i=1;i<=n;i++)yuan.s[i][i]=1;
for(int i=1;i<=n;i++)for(int u=1;u<=n;u++)mid.s[i][u]=read();
sta.line[0][0]=yuan;
sta.line[0][1]=mid;
sta.line[1][1]=mid;
sta.line[1][0]=kong;
node ansn=sumi(k-1);
matrix ans;
ans=ansn.line[0][0]*mid+ansn.line[0][1]*mid;
for(int i=1;i<=n;i++){
for(int u=1;u<=n;u++)printf("%d ",ans.s[i][u]);
printf("\n");
}
return 0;
}
第三题 生物
题面如下(点击查看)
点击查看代码
生物 (creature.c/cpp/pas)
1 题目描述
在一个无限长的一维空间中,存在着一个奇特的生物,它的身体上顺次有着 n + 1 个刻印,每个刻印可以用一个正整数来表示。已知它最后一个刻印的值为m,而其它 n 个刻印的值均不超过 m,并且两个刻印的值可以相同。
这个生物每次可以选中它的任意一个刻印,并且按照这个刻印的值 k,选择向它所在位置的前或后闪烁 k 个单位。我们称可以使得这个生物能够通过若干次闪烁,到达一维空间任何一个位置的刻印序列为超刻印序列。
现在刻印序列显然一共有 m^n 种,为了研究这个生物,请你求出其中超刻印序列的数目。
2 输入格式
仅一行两个整数,分别为 n, m。
3 输出格式
输出一行一个整数,表示超刻印序列的数目对 10^9+7 取模的结果。
4 样例输入
2 4
5 样例输出
12
6 数据范围与约定
对于前 20%的数据,保证 n,m <= 5;
对于 100%的数据,保证 1<=n<=15,1<=m<=10^8。
一切的一切都源于ax+by=gcd(x,y)
代码如下
点击查看代码
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int f=1,j=0;char w=getchar();
while(w>'9'||w<'0'){
if(w=='-')f=-1;
w=getchar();
}
while(w>='0'&&w<='9'){
j=(j<<3)+(j<<1)+w-'0';
w=getchar();
}
return f*j;
}
const int N=16,M=100000001,mod=1000000007;
int n,m,ans=1;
int mi[35],cut,zhi[10001],f[10001],tail,len;
int kkk[10001];
bool use[10001];
int sumi(int sum,int num){
int ansn=1;
mi[0]=sum;
for(int i=1;i<=33;i++)mi[i]=1ll*mi[i-1]*mi[i-1]%mod;
for(int i=0;i<=33&&num>0;i++){
if(num%2==1)ansn=(1ll*ansn*mi[i])%mod;
num/=2;
}
return ansn;
}
void rongchi(int aim,int tim,int nown,int front){
if(tim==aim+1){
kkk[aim]=(kkk[aim]+sumi(m/nown,n))%mod;
return ;
}
for(int i=front+1;i<=len;i++){
if(!use[i]){
use[i]=true;
rongchi(aim,tim+1,nown*f[i],i);
use[i]=false;
}
}
return ;
}
signed main(){
//freopen("creature.in","r",stdin);
//freopen("creature.out","w",stdout);
for(int i=2;i<=10000;i++){
if(!use[i])zhi[++tail]=i;
for(int u=1;u<=tail;u++)if(zhi[u]*i<=10000)use[zhi[u]*i]=true;
}
n=read();m=read();
int a=m;
for(int i=1;i<=tail&&zhi[i]<=a;i++){
if(a%zhi[i]==0)f[++len]=zhi[i];
while(a%zhi[i]==0){
a/=zhi[i];
}
}
if(a!=1)f[++len]=a;
memset(use,0,sizeof(use));
for(int i=1;i<=len;i++)rongchi(i,1,1,0);
ans=sumi(m,n);
long long ansn=0;
for(int i=1;i<=len;i++){
if(i%2==1)ansn=(ansn+kkk[i])%mod;
else ansn=(ansn-kkk[i])%mod;
}
printf("%d",((ans-ansn)%mod+mod)%mod);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】