2021年ACM竞赛班训练(六)题解

  • ==Problem A 逆元==
    • 题目描述
    • 输入
    • 输出
    • 题目分析
    • 代码
  • ==Problem B&C 五一假期前最后一题&女神的考验==
    • 题目描述
      • 题B
      • 题C
    • 题目分析
  • ==Problem D 整除==
    • 题目描述
    • 输入
    • 输出
    • 题目分析
    • 代码
  • ==Problem E Fibonacci==
    • 题目描述
    • 输入
    • 输出
    • 题目分析
    • 代码
  • ==Problem F C语言基础,求阶乘==
    • 题目描述
    • 输入
    • 输出
    • 题目分析
    • 代码
  • ==Problem G 推数列==
    • 题目描述
    • 输入
    • 输出
    • 题目分析
    • 代码

Problem A 逆元

题目描述

     给一个数x,求y使得x*y = 1 mod 1e9+7

输入

     T(T组样例T<=1e5)接下来T个数,每个数都小于1e9+7

输出

     每个样例输出1行

题目分析

     本题在算法竞赛入门到进阶里数论相关部分有相关知识详细的介绍,在此引用一下书里的思路。xy=1mod1e9+7,即xy除以1e9+7(下面称为m)余数是1。有解的等价条件为gcd(x,m)=1,即x和m互素,该问题就等价于求解xa+mb=1,这里可以用扩展欧几里得算法求解。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll extendgcd(ll a,ll b,ll &x,ll &y)
{if (b==0){x=1, y=0;return a;}ll t=extendgcd(b, a % b, y, x);y = y-a/b*x;return t;
}
ll fun(int a,int mod)
{ll x, y;ll d=extendgcd(a,mod,x,y);return (x%mod+mod)%mod;
}
int main()
{int T,x,y;cin>>T;while(T--){cin>>x;y=fun(x,1e9+7);cout<<y<<endl;}
}

Problem B&C 五一假期前最后一题&女神的考验

题目描述

题B

题C

题目分析

 B题利用高数可以得出x=( n + ( n^2 + 4)^0.5 )/  2C题则是利用假分数与带分数的转化

话不多说,直接上李腾飞大佬的题解
五一假期前的最后一道题
女神的考验

Problem D 整除

题目描述

     给n,求n/1+n/2+n/3+....+n/n的值

输入

     T(T<=1e3)接下来t行每行一个n(1<=n<=1e9)

输出

     每行输出一个答案

题目分析

         ∑n i=1⌊k/i⌋这个式子要想办法简化计算,

证明该式子最多只有 2√k个取值
分段讨论:

1 当 i<=√k时,因为 i 是 1 到 √ k的整数,所以最多只有 √k 个不同的 ⌊k/i⌋值。
2 当 i>√k时,⌊k/i⌋<=√k,又因为式子取整了,所以式子只能取1 到 √k 的整数,故最多也只有 √k 个不同的 ⌊k/i⌋值。

综上所述,⌊k/i⌋最多只有 2√ k个取值
通过以上步骤,我们可以知道这个答案由连续 2√k 段不同的取值组成,那么我们只需要确定每种取值是下界 l 和 上界 r。通过 ∑ri=l⌊k/i⌋∗i=∑ri=l⌊k/l⌋∗i=⌊k/l⌋∗(∑ri=li) 即可求得每一段对答案的贡献。(∑ri=li) 可以用等差数列求和公式计算。

已知下界求上界
假设我们知道一段相同取值的下界是 x,若能求出上界,我们问题便解决了。
猜想若下界是 x,上界是 r=⌊k/⌊k/x⌋⌋

第一步、求证 ⌊k/x⌋=⌊k/r⌋

由定义式可知

r∗⌊k/x⌋+q=k③,其中 0<=q<⌊k/x⌋,所以 ⌊k/r⌋=⌊r∗⌊k/x⌋+qr⌋=⌊k/x⌋+⌊qr⌋>=⌊k/x⌋
r>=⌊k/(k/x)⌋=x,所以 ⌊k/x⌋>=⌊k/r⌋

综上 ⌊k/x⌋=⌊k/r⌋。

第二步、求证 ⌊k/(r+1)⌋≠⌊k/x⌋
假设 ⌊k/(r+1)⌋=⌊k/x⌋
那么有 (r+1)∗⌊k/x⌋+q′=k,其中 0<=q<r+1
把式子变化一下:

r∗⌊k/x⌋+⌊k/x⌋+q′=k④

③④ 联立,有:
⌊k/x⌋+q′<⌊k/x⌋因为 q′>=0,所以该式子矛盾,故假设不成立。
通过这两步及之前的单调性,我们知道 ⌊k/⌊k/x⌋⌋一定是上界

则这道题的解题思路就是
····设 l=1,算出上界 r。计算这段的贡献
····使 l=r+1,即跳到下一段计算贡献。
····重复知道算完 [1,n]里所有段。

代码

#include<bits/stdc++.h>
#define fer(i,a,b) for(re i = a ; i <= b ; ++ i)
#define re register int
typedef long long ll ;
using namespace std;
const int N =  1e6 + 10 , M = 1010 , inf = 0x3f3f3f3f , mod = 1e9 + 7 ;
int main()
{int n ;cin >> n ;long long res = 0 ;for(int l = 1 , r ; l <= n ; l = r + 1){r = n / (n / l) ;res += (r - l + 1) * (n / l) ;}cout << res << endl;  // 答案return 0;
}

Problem E Fibonacci

题目描述

     我们知道斐波那契数列F0=0,F1=1,Fn=Fn−1+Fn−2。我们还知道矩阵的运算是满足结合律的求Fn mod 10^4。

输入

     多组数据,每组数据一行,一个整数n。输入以-1结束。

输出

     对于每组数据,输出Fn mod 10^4。

题目分析

     Fn mod 10000 的结果每300000次循环一次所以只需要打标求出前3000000项即可

代码

     东子哥的做法
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 998244353
#define rg register
#define RP(i,a,b) for(register ll i=a;i<=b;i++)
#define DRP(i,a,b) for(register ll i=a;i>=b;i--)
#define fre(z) freopen(z".in","r",stdin),freopen(z".out","w",stdout)
//#define lll long long
//#define lll __int128
ll f[3000006]={0};
int main(void)
{f[0]=0,f[1]=1;ll n;RP(i,2,3000000)   f[i]=(f[i-1]+f[i-2])%10000;while(1){cin>>n;if (n==-1) break;cout<<f[n%3000000]<<endl;}return 0;
}

Problem F C语言基础,求阶乘

题目描述

     通过我们前面所学习的快速傅里叶变换,快速数论变换,拉格朗日差值定理,多项式多点求值以及min25筛,现在给你一个n,求n!mod 1e9+7

输入

     t,代表样例个数(1<=t<=100)接下来n行每行一个数n  (1<=n<=1e9)

输出

     对于每个数n输出一行答案

题目分析

     这题太难,so下面是东子哥发的洛谷的题解

P5282 【模板】快速阶乘算法 题解

代码

     大佬的代码
// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;const int N=262144+10;typedef unsigned long long ll;
const int P=65536;const int SF=16;const int msk=65535;ll mod;ll PP;
typedef long double ld;const ld pi=acos(-1.0);
inline ll po(ll a,ll p){ll r=1;for(;p;p>>=1,a=a*a%mod)if(p&1)r=r*a%mod;return r;}
struct cmp
{ld r;ld v;friend cmp operator +(cmp a,cmp b){return (cmp){a.r+b.r,a.v+b.v};}friend cmp operator -(cmp a,cmp b){return (cmp){a.r-b.r,a.v-b.v};}friend cmp operator *(cmp a,cmp b){return (cmp){a.r*b.r-a.v*b.v,a.r*b.v+a.v*b.r};}void operator /=(const int& len){r/=len;v/=len;}
}rt[2][22][N],tr[N],tr1[N],tr2[N],tr3[N],tr4[N],tr5[N],tr6[N];
int rv[22][N];ll m13[N],m14[N],m23[N],m24[N];
inline void pre()
{for(int d=1;d<=18;d++)for(int i=1;i<(1<<d);i++)rv[d][i]=(rv[d][i>>1]>>1)|((i&1)<<(d-1));for(int d=1,t=1;d<=18;d++,t<<=1)for(int i=0;i<(1<<d);i++)rt[0][d][i]=(cmp){cos(pi*i/t),sin(pi*i/t)};for(int d=1,t=1;d<=18;d++,t<<=1)for(int i=0;i<(1<<d);i++)rt[1][d][i]=(cmp){cos(pi*i/t),-sin(pi*i/t)};
}inline void fft(cmp* a,int len,int d,int o)
{for(int i=1;i<len;i++)if(i<rv[d][i])swap(a[i],a[rv[d][i]]);cmp* w;int i;for(int k=1,j=1;k<len;k<<=1,j++)for(int s=0;s<len;s+=(k<<1))for(i=s,w=rt[o][j];i<s+k;i++,++w){cmp a1=a[i+k]*(*w);a[i+k]=a[i]-a1;a[i]=a[i]+a1;}if(o)for(int i=0;i<len;i++)a[i]/=len;
}inline void dbdft(ll* a,int len,int d,cmp* op1,cmp* op2)
{for(int i=0;i<len;i++)tr[i]=(cmp){(ld)(a[i]>>SF),(ld)(a[i]&msk)};fft(tr,len,d,0);tr[len]=tr[0];for(cmp* p1=tr,*p2=tr+len,*p3=op1;p1!=tr+len;++p1,--p2,++p3)(*p3)=(cmp){p1->r+p2->r,p1->v-p2->v}*(cmp){0.5,0};for(cmp* p1=tr,*p2=tr+len,*p3=op2;p1!=tr+len;++p1,--p2,++p3)(*p3)=(cmp){p1->r-p2->r,p1->v+p2->v}*(cmp){0,-0.5};
}inline void dbidft(cmp* tr,int len,int d,ll* a,ll* b)
{fft(tr,len,d,1);for(int i=0;i<len;i++)a[i]=(ll)(tr[i].r+0.5)%mod;for(int i=0;i<len;i++)b[i]=(ll)(tr[i].v+0.5)%mod;
}inline void poly_mul(ll* a,ll* b,ll* c,int len,int d)//以上都是任意模数fft的板子
{dbdft(a,len,d,tr1,tr2);dbdft(b,len,d,tr3,tr4);for(int i=0;i<len;i++)tr5[i]=tr1[i]*tr3[i]+(cmp){0,1}*tr2[i]*tr4[i];for(int i=0;i<len;i++)tr6[i]=tr2[i]*tr3[i]+(cmp){0,1}*tr1[i]*tr4[i];dbidft(tr5,len,d,m13,m24);dbidft(tr6,len,d,m23,m14);for(int i=0;i<len;i++)c[i]=m13[i]*PP%mod;for(int i=0;i<len;i++)(c[i]+=(m23[i]+m14[i])*P+m24[i])%=mod;
}namespace iter
{ll f[N];ll g[N];ll h[N];ll ifac[N];inline void ih(){ifac[0]=ifac[1]=1;for(int i=2;i<min((ll)N,mod);i++)ifac[i]=(mod-mod/i)*ifac[mod%i]%mod;for(int i=1;i<min((ll)N,mod);i++)(ifac[i]*=ifac[i-1])%=mod;}inline void calch(ll del,int cur,ll* ip,ll* op){int d=0;int len=1;while(len<=cur+cur+cur)len<<=1,d++;for(int i=0;i<=cur;i++)f[i]=ip[i]*ifac[i]%mod*ifac[cur-i]%mod;for(int i=cur-1;i>=0;i-=2)f[i]=(mod-f[i])%mod;for(int i=0;i<=cur+cur;i++)g[i]=po((del+mod-cur+i)%mod,mod-2); for(int i=cur+1;i<len;i++)f[i]=0;for(int i=cur+cur+1;i<len;i++)g[i]=0;poly_mul(f,g,h,len,d);//卷积求出h' ll xs=1;ll p1=del-cur;ll p2=del;for(int i=p1;i<=p2;i++)(xs*=i)%=mod;for(int i=0;i<=cur;i++,p1++,p2++)//双指针求出系数 {op[i]=h[i+cur]*xs%mod;(xs*=po(p1,mod-2))%=mod,(xs*=(p2+1))%=mod;}  }
}ll val[N];ll fv1[N];ll fv2[N];
inline void solve(int n)//倍增
{int hb=0;for(int p=n;p;p>>=1)hb++;val[0]=1;for(int z=hb,cur=0;z>=0;z--){if(cur!=0)//把d乘2 {iter::calch(cur+1,cur,val,fv1);for(int i=0;i<=cur;i++)val[cur+i+1]=fv1[i];val[cur<<1|1]=0;iter::calch(cur*po(n,mod-2)%mod,cur<<1,val,fv2);cur<<=1;for(int i=0;i<=cur;i++)(val[i]*=fv2[i])%=mod;}if((n>>z)&1)//把d加1 {for(int i=0;i<=cur;i++)(val[i]*=(ll)(n*i)+cur+1)%=mod;cur|=1;val[cur]=1;for(int i=1;i<=cur;i++)(val[cur]*=(ll)cur*n+i)%=mod;}}
}
int main()
{pre();int n;scanf("%d%lld",&n,&mod);iter::ih();int bl=sqrt(n);PP=(ll)P*P%mod;solve(bl);ll res=1;for(int i=0,id=0;;i+=bl,id++)//分块 {if((ll)i+bl>n){for(int j=i+1;j<=n;j++)(res*=j)%=mod;break;}(res*=val[id])%=mod;}printf("%lld",res);return 0;//拜拜程序~
}

Problem G 推数列

题目描述

     已知数列a1)n<=k时,an=n2)n>k时,an=an-1+2an-2+3an-3+....+kan-k给n,k求an%(1e9+7)

输入

     第一行一个数T(1<=T<=30)接下来T行每行一个n,k1<=k<=501<=n<=1e18

输出

     每行对应的答案

题目分析

代码

#include<bits/stdc++.h>
using namespace std;
long long  n;//矩阵的阶
long long  N;
#define  ll long long
const ll Mod=1e9+7;
struct mm{long long  m[51][51];mm(){memset(m,0,sizeof(m));}
};mm multi(mm a ,mm b){mm res;for( ll i=1;i<=N;i++){for( ll j=1;j<=N;j++){for( ll k=1;k<=N;k++){res.m[i][j]=(res.m[i][j] + a.m[i][k] * b.m[k][j]) % Mod;}}}return res;
} // 矩阵乘法
mm fastm(mm a ,ll n){mm res;for( ll i=0;i<=N;i++){res.m[i][i]=1;}while(n){if(1&n){res=multi(res,a);}a=multi(a,a);n=n/2;}return res;
}
int main(){int t;cin>>t;while(t--){long long k;cin>>n>>k;N=k;mm a;for( int i=1;i<=k;i++){a.m[1][i]=i;}for( int i=1;i<=k-1;i++){a.m[i+1][i]=1;}mm res=fastm(a,n-k);
//      for( int i=1;i<=k;i++){//          for( int j=1;j<=k;j++){//              cout<<res.m[i][j]<<" ";
//          }
//          cout<<endl;
//      }long long ans=0;for( int i=1;i<=k;i++){ans+=res.m[1][i]*(k-i+1)%Mod;   }cout<<(ans)%Mod<<endl;}
}

2021年ACM竞赛班训练(六)题解相关推荐

  1. BUCTOJ2021年ACM竞赛班训练九题解

    BUCTOJ2021年ACM竞赛班训练九题解 问题A 问题B 问题C 问题D 问题E 问题F 问题A 原题链接 A题题解: 首先让我们看看这个题的题目,ummm-好像要找题目,好吧,我们去看看题目在哪 ...

  2. 2021年ACM竞赛班训练(十一)2021.5.20-问题 E: 调皮的摩尔-题解

    传送门 Balloon 题目描述 输入描述 输出描述 样例一 输入 输出 说明 提示 题目分析 注意事项 AC代码 Balloon 传送门 时间限制:1秒 空间限制:128M 题目描述 儿童节突然火起 ...

  3. buctoj2021年ACM竞赛班训练(七)题解

    A: 玩游戏 题意:初始有一堆石子共n个,双方轮流行动,每次可以从中取出恰好完全平方数(1.4.9--)个石子,不可以不取石子直接跳过回合.双方都足够聪明,会按最优的方式来游玩,无法行动的人输掉该游戏 ...

  4. BUCT-2021年ACM竞赛班训练(六)2021.4.29-问题 C:女神的考验-题解

    传送门 女神的考验 题目描述 输入描述 输出描述 样例一 输入 输出 题目分析 注意事项 AC代码 女神的考验 传送门 时间限制:1秒 空间限制:128M 题目描述 星空点点,墨日曜淡.世界芳华灼灼, ...

  5. 集合划分讲解-And-2021年ACM竞赛班训练(九)2021.5.20-问题 E: 登上火星-题解

    集合划分 集合划分,把 n n n个数分成 k k k个集合,不能包含空集,所有的划分数量记为斯大林数,用 S ( n , k ) S(n,k) S(n,k)表示. 目前斯大林数没有直接的公式,但是有 ...

  6. BUCT-2021年ACM竞赛班训练(一)2021.3.25-问题 A: 大佬的高级IDLE-题解

    目录 大佬的高级IDLE 题目描述 输入描述 输出描述 示例1 输入 输出 说明 题目分析 解题思路 并查集离散化 AC代码 大佬的高级IDLE 传送门 时间限制:2秒 空间限制:128M 题目描述 ...

  7. 牛客竞赛数学专题班生成函数I 题解

    牛客竞赛数学专题班生成函数I 题解 题单链接 背包 题目链接 题意 总共有888个物品,对于每个物品的选法都有要求,问带nnn个物品的方案数. 思路 构造生成函数,并将等比级数转为合式(∏i=0xi= ...

  8. ICPC训练联盟2021寒假冬令营(7)部分题解

    ICPC训练联盟2021寒假冬令营(7)部分题解: A - Doubles As part of an arithmetic competency program, your students wil ...

  9. ACM如何入门,ACM竞赛需要学习哪些算法?

    #################成绩################## 大一:2017年4月份"玲珑杯"河南工业大学2017年ACM程序设计大赛暨河南高校邀请赛,获得银奖 20 ...

最新文章

  1. 实时摄像头数据传输丢包问题
  2. RSA的密钥把JAVA格式转换成C#的格式
  3. 终端链接操作redis
  4. html css精灵,谈谈CSS Sprites(css精灵)
  5. 电大计算机应用技术基础视频,电大形成性测评-计算机应用技术基础01
  6. php new static,PHP 的 new static 和 new self
  7. 框架下cookie的使用_aspnetcore自带cookie的认证期限分析
  8. python的__slots__
  9. python判断文件格式_Python判断上传文件类型
  10. 微信小程序网络请求封装
  11. html标签和css参数
  12. svg 树状图_树状图(关系图)
  13. java 动态修改配置文件_Java 项目中一种简单的动态修改配置即时生效的方式 WatchService...
  14. 求任意一个自然数n的立方均可写成n个连续奇数之和。
  15. 2.8.1利用“直流扫描分析”测试基本共射放大电路电压传输特性
  16. Java代码实现阿里云视频上传
  17. yield()函数的使用
  18. 超详细的canal使用总结
  19. Tree Shaking和sideEffects配置
  20. 解决华为手机不能用USB链接电脑的问题

热门文章

  1. 2021-04-04Excel表格
  2. 不要和好朋友合伙开公司,不要和亲戚合伙做买卖。
  3. 超详细如何配置ACL
  4. 天翼云桌面 居家远程办公更舒心
  5. Tencent APIJSON-自动化接口和文档 ORM 库开源啦
  6. springboot解析不到docker中含有点号的环境变量
  7. Redis学习 Linux联网与主机互ping测试
  8. 【DaVinci Developer专题】-23-IDT高阶应用:结构体类型的数组
  9. 在ios中无法获取ajax返回数据类型,在iOS10系统中微信后退无法发起ajax请求的问题解决办法...
  10. 继Google AI黑人女性离职后又一女高管被解雇,A I伦理还有很长的路