您的位置:首页 > 其它

数论&&快排&&dp板子

2017-11-09 07:19 309 查看

板子日DAY2

逆元

线性递推求逆元

一个易懂的证明

ll inv[30000529];
int main()
{
ll n=read(),p=read();
inv[1]=1;
for(int i=2;i<=n;i++){
inv[i]=(p-p/i)*inv[p%i]%p;
}
for(int i=1;i<=n;i++){
cout<<inv[i]<<"\n";
}
return 0;
}


小费马

注意满足 ap−1=1(modp) 的条件为gcd(a,p)=1

ll fast_pow(int a,int p)
{
ll ans=1;
for(;p;p>>=1,a=(a*a)%MOD){
if(p&1)
{
ans=(ans*a)%MOD;
}
}
return ans;
}
int main()
{
//ios::sync_with_stdio(false);
int n=read(),p=read();
MOD=p;
for(int i=1;i<=n;i++)
cout<<fast_pow(i,p-2)<<"\n";
return 0;
}


线性阶乘+小费马求逆元



转自luogu 感谢作者:积累

int MOD;
long long  fast_pow(long long a,int p)
{
long long ans=1;
for(;p;p>>=1,a=(a*a)%MOD){
if(p&1)
{
ans=(ans*a)%MOD;
}
}
return ans;
}
long long  a[3000001],f[3000001],g[3000001];
int main()
{
//ios::sync_with_stdio(false);
int n=read(),p=read();
MOD=p;
f[0]=1;
for(int i=1;i<=n;i++){
f[i]=(f[i-1]*i)%MOD;
}
g
=fast_pow(f
,p-2);
for(int i=n-1;i>=1;i--){
g[i]=(g[i+1]*(i+1))%MOD;
}
for(int i=1;i<=n;i++){
cout<<(g[i]*f[i-1]%MOD)<<"\n";
}
return 0;
}


扩展欧几里得(证明在这里

ll exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1;
y=0;
return a;
}
else {
exgcd(b,a%b,y,x);
/** int t=x;
x=y;
y=(t-a/b*y);*/
y-=(a/b)*x;
}
}
int main()
{
//ios::sync_with_stdio(false);
int a=read(),b=read(),x,y;
exgcd(a,b,x,y);
while(x<=0){
x+=b;
}cout<<x;
return 0;
}


中国剩余定理

(模数互素)

证明在这里

ll a[1000],m[1000];
void exgcd(ll a,ll b,ll &x,ll &y){
if(b==0){
x=1,y=0;return ;
}
else {
exgcd(b,a%b,y,x);
y-=a/b*x;
}
}
int main()
{
//ios::sync_with_stdio(false);
ll n=read(),x=read(),y=read();
for(ll i=1;i<=n;i++){
m[i]=read(),a[i]=read();
}
ll M=1;
for(ll i=1;i<=n;i++){
M*=m[i];
}
ll ans=0;
for(ll i=1;i<=n;i++){
ll mi=M/m[i];
ll x,y;
exgcd(mi,m[i],x,y);x+=m[i];
ans=(ans+a[i]*mi*x)%M;
ans%=M;
}


线性筛素数

(详见传送门

notprime[1]=notprime[0]=1;
for(int i=2;i<=n;i++){
if(!notprime[i]){
prime[++cnt]=i;
}
for(int j=1;j<=cnt&&prime[j]*i<=n;j++){
notprime[prime[j]*i]=1;
if(prime[j]%i==0)break;
}
}


矩阵加速

(左横右竖)

const int MOD= 1e9+7;
struct matrix{
int n,m;
ll a[200][200];
matrix operator *(matrix &b) {       //别忘&!!!
matrix ans;
if(b.n!=n)cout<<"error";
ans.n=n,ans.m=b.m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
ans.a[i][j]=0;
}
}                        ///别忘初始化!!!
for(int i=1;i<=n;i++){
for(int j=1;j<=b.m;j++){
for(int k=1;k<=m;k++){
ans.a[i][j]+=(a[i][k]*b.a[k][j])%MOD;
ans.a[i][j]%=MOD;
}
}
}
return ans;
}
void show(){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<a[i][j]<<" ";
}cout<<"\n";
}
}
};
matrix fast_pow(matrix &a,ll p){  ///这个引用很玄学 不带可能会崩
matrix ans;
ans=a;
for(int i=1;i<=a.n;i++){
for(int j=1;j<=a.m;j++){
if(i==j)ans.a[i][j]=1;
else  ans.a[i][j]=0;
}
}
for(;p;p>>=1,a=a*a){
if(p&1) ans=ans*a;
}

return ans;
}


Lucas定理

ll f[maxn],MOD;
ll fast_pow(ll a,ll p){
ll ans=1;
for(;p;p>>=1,a=a*a%MOD){
if(p&1){
ans*=a;
ans%=MOD;
}
}
return ans;
}
ll C(ll n, ll m){
if(m<n) return 0;
return f[m]*fast_pow((f[m-n]*f
)%MOD,MOD-2)%MOD;
}
ll lucas(ll n,ll m){
if(n==0) return 1;
else return (C(n%MOD,m%MOD)*lucas(n/MOD,m/MOD))%MOD;
}
int main()
{
//ios::sync_with_stdio(false);
int T=read();
while(T--){
ll n=read(),m=read();MOD=read();
f[0]=1;
for(int i=1;i<=MOD;i++){
f[i]=f[i-1]*i%MOD;
}
cout<<lucas(m,n+m)<<"\n";
}
return 0;
}


快排

void qsort(int l,int r){
if(l>=r)return;
srand(time(NULL));
int k=rand()%(r-l+1)+l;
swap(a[l],a[k]);
int i=l,j=r;
int sd=a[l];
while(i<j){
while(i<j&&a[j]>=sd)--j;
a[i]=a[j];
while(i<j&&a[i]<=sd)++i;
a[j]=a[i];
}
a[i]=sd;
qsort(l,i);
qsort(i+1,r);
return;
}


最长公共子序列

(特解&&标解)

const int maxn=100100;
int mmp[maxn],g[maxn],cnt,a[maxn],b[maxn],dp[1001][1001];
void solve1(int n){
for(int i=1;i<=n;i++){
int a=read();
mmp[a]=i;
}
for(int i=1;i<=n;i++){
int a=read();
int b=mmp[a];
if(b>g[cnt]){
g[++cnt]=b;
}
else {
int l=1,r=cnt,mid;
while(l<=r){
mid=l+r>>1;
if(g[mid]>b){
r=mid-1;      //二分别写反了!!
}else l=mid+1;
}
if(l!=0)g[l]=b;
//*upper_bound(g+1,g+cnt+1,b)=b;
}
}
cout<<cnt;
}
void solve2(int n){
for(int i=1;i<=n;i++){
a[i]=read();
}
for(int i=1;i<=n;i++){
b[i]=read();
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i]==b[j]){
dp[i][j]=dp[i-1][j-1]+1;
}
else {
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
cout<<dp

;
}
int main()
{
//ios::sync_with_stdio(false);
int n=read();
if(n<=1000)solve2(n);
else solve1(n);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  模板