任意门

  回来拉模版的时候意外发现这个题还没写题解,所以就随便补点吧。

  题意其实就是要你求n的阶乘在模意义下的值。

  首先找出来一个最大的$m$满足$m^2<=n$,对于大于$m^2$部分的数我们直接暴力求就行了,问题是求$m^2$以内的答案。

  先构造一个多项式$f(x)=(x+1)(x+2)(x+3)……(x+m)$,然后求它在$x=0、x=m……x=m(m-1)$位置的值,然后求个值全部乘起来就行了。

  

  稍微说下怎么做多点求值,构造两个多项式

  $$G_1(x)=(x-x_1)(x-x_2)……(x-x_{\left\lfloor\frac{m}{2}\right\rfloor})=x(x-m)……(x-\left\lfloor\frac{m}{2}\right\rfloor m)$$

  $$G_2(x)=(x-x_{\left\lfloor\frac{m}{2}\right\rfloor+1})……(x-x_m)=(x-\left\lfloor\frac{m}{2}\right\rfloor m-m)……(x-m^2+m)$$

  然后拿$f(x)$对$G_1(x)$取模得到一个$\left\lfloor\frac{m}{2}\right\rfloor$次的多项式,这个多项式在$x_1、x_2……x_{\left\lfloor\frac{m}{2}\right\rfloor}$位置的值跟$f(x)$是一样的(这是因为构造出来的式子在这些位置都等于0,而我们可以把多项式除法看成很多次减法,所以这个值不会变),后半部分同理用$G_2(x)$处理,这个时候问题规模就减半了,由此递归即可。

  题目最后复杂度是$O(\sqrt{n}log^2\sqrt{n})$

  

  

#include<cstdio>
#include<cstring>
#include<algorithm>
#define lp (p<<1)
#define rp ((p<<1)|1)
#define ll long long
#define MN 200200
using namespace std;
int read_p,read_ca;
inline int read(){
read_p=;read_ca=getchar();
while(read_ca<''||read_ca>'') read_ca=getchar();
while(read_ca>=''&&read_ca<='') read_p=read_p*+read_ca-,read_ca=getchar();
return read_p;
}
int _n,n,m,t,e[MN],_e[MN],Mmh=,D[MN],C_a[MN],C_b[MN],C_c[MN],N_c[MN],D_a[MN],D_b[MN],D_c[MN],tot,gg=,MMH[MN],L[MN*];
int rt[MN*],B[MN*],sz=;
int MOD=;
inline void M(int &x){while(x>=MOD)x-=MOD;}
inline int mi(int a,int b){
int mmh=;
while (b){
if (b&) mmh=1LL*mmh*a%MOD;
b>>=;a=1LL*a*a%MOD;
}
return mmh;
}
inline void inv(){
int base=mi(gg,(MOD-)/tot),_base=mi(base,MOD-);
e[]=_e[]=;
for (register int i=;i<=tot;i++) e[i]=1LL*e[i-]*base%MOD,_e[i]=1LL*_e[i-]*_base%MOD;
}
inline void NTT(int N,int a[],int w[]){
register int i,j,k,m,z;
for (i=j=;i<N;i++){
if (i>j) swap(a[i],a[j]);
for (k=N>>;(j^=k)<k;k>>=);
}
for (i=;i<=N;i<<=)
for (m=i>>,j=;j<N;j+=i)
for (k=;k<m;k++){
z=1LL*a[j+k+m]*w[tot/i*k]%MOD;
a[j+k+m]=a[j+k]>z?a[j+k]-z:MOD-z+a[j+k];
a[j+k]=a[j+k]-MOD+z;if (a[j+k]<) a[j+k]+=MOD;
}
}
inline void cc(int N,int a[],int b[],int c[]){
memcpy(C_a,a,N<<);memcpy(C_b,b,N<<);
NTT(N,C_a,e);NTT(N,C_b,e);
for (register int i=;i<N;i++) c[i]=1LL*C_a[i]*C_b[i]%MOD;
NTT(N,c,_e);
int w=mi(N,MOD-);
for (register int i=;i<N;i++) c[i]=1LL*c[i]*w%MOD;
}
inline void cc(int n,int m,int a[],int b[],int c[]){
int N;
for (N=;N<(n+m);N<<=);
memcpy(C_a,a,n<<);memcpy(C_b,b,m<<);
fill(C_a+n,C_a+N,);fill(C_b+m,C_b+N,);
NTT(N,C_a,e);NTT(N,C_b,e);
for (register int i=;i<N;i++) c[i]=1LL*C_a[i]*C_b[i]%MOD;
NTT(N,c,_e);
int w=mi(N,MOD-);
for (register int i=;i<N;i++) c[i]=1LL*c[i]*w%MOD;
}
inline void ny(int p,int a[],int b[]){
if (p==) b[]=mi(a[],MOD-);else{
ny((p+)>>,a,b);
int N=;
while (N<(p<<))N<<=;
copy(a,a+p,N_c);fill(N_c+p,N_c+N,);
NTT(N,N_c,e);NTT(N,b,e);
for (register int i=;i<N;i++) b[i]=(2LL-1LL*N_c[i]*b[i]%MOD+MOD)*b[i]%MOD;
NTT(N,b,_e);
int w=mi(N,MOD-);
for (register int i=;i<N;i++) b[i]=1LL*b[i]*w%MOD;
fill(b+p,b+N,);
}
}
inline void re_copy(int n,int a[],int b[]){for (register int i=;i<n;i++) b[i]=a[n-i-];}
inline void div(int n,int m,int a[],int b[],int d[],int r[]){
int N=,t=n-m+,i;
while (N<t<<)N<<=;
memset(D_a,,N<<);
memset(D_b,,N<<);
memset(D_c,,N<<);
memset(d,,N<<);
re_copy(m,b,D_b);
re_copy(n,a,D_a);
ny(t,D_b,D_c);
for (N=;N<(n<<);N<<=);
cc(n,t,D_a,D_c,D_b);
re_copy(t,D_b,d);
fill(d+t,d+N,);
cc(t,m,d,b,D_a);
for (i=;i<m;i++) r[i]=(1LL*a[i]-D_a[i]+MOD)%MOD;
fill(r+m,r+N,);
}
inline bool ju(int x){
int u=MOD-;
for (register int i=;i*i<=u;i++)
if (u%i==) if (mi(x,u/i)==) return ;
return ;
}
int mmh=;
inline void Mmhp(int p,int l,int r){
if (l==r){
L[p]=sz;
rt[sz]=l;
rt[sz+]=;
sz+=;
return;
}
int mid=l+r>>;
Mmhp(lp,l,mid);Mmhp(rp,mid+,r);
cc(mid-l+,r-mid+,rt+L[lp],rt+L[rp],rt+sz);
L[p]=sz;
sz+=r-l+;
}
inline void Mmhrt(int p,int l,int r){
if (l==r){
L[p]=sz;
rt[sz]=(MOD-1LL*m*l%MOD)%MOD;
rt[sz+]=;
sz+=;
return;
}
int mid=l+r>>;
Mmhrt(lp,l,mid);Mmhrt(rp,mid+,r);
cc(mid-l+,r-mid+,rt+L[lp],rt+L[rp],rt+sz);
L[p]=sz;
sz+=r-l+;
}
inline void _Mmh(int p,int l,int r,int fi,int LL){
div(LL,r-l+,B+fi,rt+L[p],D,B+sz);
int mid=l+r>>,s=sz;
sz+=r-l+;
if (l==r) mmh=1LL*B[s]*mmh%MOD;else _Mmh(lp,l,mid,s,r-l+),_Mmh(rp,mid+,r,s,r-l+);
}
int main(){
register int i;
n=read();
MOD=read();
if (n>=MOD) return printf("0\n"),;
while(ju(gg))gg++;
for (m=;(m+)*(m+)<=n;m++);
for (tot=;tot<((m+)<<);tot<<=);inv();
for (i=m*m+;i<=n;i++) mmh=1LL*mmh*i%MOD;
sz=;Mmhp(,,m);
for (i=L[];i<=L[]+m;i++) B[i-L[]]=rt[i];
sz=;Mmhrt(,,m-);
sz=m+;_Mmh(,,m-,,m+);
if (n&) mmh=1LL*mmh*mi(,MOD-)%MOD;
printf("%d\n",mmh);
}

51nod 1387 移数字的更多相关文章

  1. 51nod 1770 数数字

    1770 数数字 基准时间限制:1 秒 空间限制:262144 KB 分值: 20 难度:3级算法题  收藏  关注 统计一下 aaa ⋯ aaan个a × b 的结果里面 ...

  2. ACM学习历程—51NOD 1770数数字(循环节)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1770 这是这次BSG白山极客挑战赛的A题.由于数字全部相同,乘上b必然会 ...

  3. 51nod 1132 覆盖数字的数量 V2

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1132 题意是给定a,b,l,r求[l,r]内有几个整数可以表示成ax+b ...

  4. 51nod 1009:数字1的数量

    1009 数字1的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题  收藏  关注 给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个 ...

  5. 51NOD 1371填数字

    传送门 分析 此题关键在于想出dp[i][j][k]代表考虑到第i行,还能放1的的共有j列,还能放2的共有k行.之后就枚举每一行是没有还是1个1还是2个1还是1个2,然后转移即可. 代码 #inclu ...

  6. 51nod 1770 数数字 找规律,注意进位,时间复杂度O(n)

    题目: 这题很简单,找规律即可. 考虑两次进位: 1.a*b时的进位. 2.aa*b时加法时进位. 代码: #include <bits\stdc++.h> using namespace ...

  7. 51nod P1354 选数字 题解

    每日一题 day8 打卡 Analysis 背包+离散化 这题是我们一次模拟赛的T2,结果我的暴力全TLE了. 关键是如果将两个因数的乘积离散化在因数数组中之后等于这个乘积本身,说明a[j]*in离散 ...

  8. 清北学堂2018DP&图论精讲班 DP部分学习笔记

    Day 1 上午 讲的挺基础的--不过还是有些地方不太明白 例1 给定一个数n,求将n划分成若干个正整数的方案数. 例2 数字三角形 例7 最长不下降子序列 以上太过于基础,不做深入讨论 例3 给定一 ...

  9. csp-s 考前刷题记录

    洛谷 P2615 神奇的幻方 洛谷 P2678 跳石头 洛谷 P1226 [模板]快速幂||取余运算 洛谷 P2661 信息传递 LOJ P10147 石子合并 LOJ P10148 能量项链 LOJ ...

随机推荐

  1. 分布式监控系统开发【day37】:服务端生成配置数据(四)

    一.目录结构 二.引子与代码 1.客户端获取服务列表接口 1.解决了什么问题 客户端要给我获取服务列表的的时候,他肯定要告诉他是谁?他怎么告诉我,客户端必须有一个id号 Saltsack你装一个客户端 ...

  2. Groovy 设计模式 -- 组合模式

    Composite Pattern http://groovy-lang.org/design-patterns.html#_chain_of_responsibility_pattern 组合模式, ...

  3. uploadPreview上传图片前预览图片

    uploadPreview.js是一款图片上传前的预览插件.谷歌.火狐.IE都可以兼容,但是不支持safari. 相关的html代码: <!DOCTYPE html PUBLIC "- ...

  4. Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC

    解决Invalid character found in the request target. The valid characters are defined in RFC 7230 and RF ...

  5. MySql的事务控制(TCL语言)

    ⒈事务 一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行. ⒉事务的特性(ACID) 1.原子性(Atomicity):一个事务不可再分割,要么都执行要么都不执行. 2. ...

  6. ActiveMQ之topic主题模式

    开发环境我们使用的是ActiveMQ 5.11.1 Release的Windows版,官网最新版是ActiveMQ 5.12.0 Release,大家可以自行下载,下载地址.需要注意的是,开发时候,要 ...

  7. Task.Run与Task.Factory.StartNew的区别

    Task是可能有延迟的工作单元,目的是生成一个结果值,或产生想要的效果.任务和线程的区别是:任务代表需要执行的作业,而线程代表做这个作业的工作者. 在.Net 4中,Task.Factory.Star ...

  8. Elasticsearch JAVA api轻松搞定groupBy聚合

    本文给出如何使用Elasticsearch的Java API做类似SQL的group by聚合. 为了简单起见,只给出一级groupby即group by field1(而不涉及到多级,例如group ...

  9. alembic使用

    前言 alembic是SQLAlchemy作者编写的控制 model 版本的模块,配合SQLAlchemy使用更佳 正文 安装 pip install alembic alembic是可以在DOS中执 ...

  10. Flask上下文管理源码--亲自解析一下

    前戏 偏函数 def index(a,b): return a+b # 原来的调用方法 # ret=index(1,2) # print(ret) # 偏函数--帮助开发者自动传递参数 import ...