今天下午学习了二项式反演,做了一道错排的题,开始了苦逼的经历。

显然答案是C(︀n,k)︀*H(n − k).
其中H(i)为长度为i的错排序列

然后经过课件上一番二项式反演的推导

我就写了个扩展卢卡斯然后交上去了。

一直t啊.....

我算了算复杂度差不多是O(T*P*log^3P)

后来剪了剪枝,应该低了点。

还是t啊.....

我搜了搜题解发现没有我这么写的。

看了一下错排是有规律的,果然还是打表大法吼啊。

发个正解

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll qmod(ll n,ll m,ll p)
{
ll ans=;
while(m)
{
if(m&)ans=ans*n%p;
n=n*n%p;m>>=;
}
return ans;
}
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b){
x=;y=;return;
}
exgcd(b,a%b,y,x);y-=a/b*x;
}
ll inv(ll n,ll p)
{
if(!n)return ;
ll a=n,b=p,x=,y=;
exgcd(a,b,x,y);
x=(x%b+b)%b;
if(!x)x+=b;
return x;
}
ll mul(ll n,ll pi,ll pk)
{
if(!n)return 1ll;
ll ans=;
if(n/pk)
{
for(ll i=;i<=pk;++i)
if(i%pi)ans=ans*i%pk;
ans=qmod(ans,n/pk,pk)%pk;
}
for(ll i=;i<=n%pk;++i)
if(i%pi)ans=ans*i%pk;
return ans*mul(n/pi,pi,pk)%pk;
}
int C(ll n,ll m,ll p,ll pi,ll pk)
{
if(m>n)return ;
ll a=mul(n,pi,pk),b=mul(m,pi,pk),c=mul(n-m,pi,pk);
ll k=,ans;
for(ll i=n;i;i/=pi)k+=i/pi;
for(ll i=m;i;i/=pi)k-=i/pi;
for(ll i=n-m;i;i/=pi)k-=i/pi;
ans=a*inv(b,pk)%pk*inv(c,pk)%pk*qmod(pi,k,pk)%pk;
return ans*(p/pk)%p*inv(p/pk,pk)%p;//CRT
}
bool v[];
int pp[],cnt;
void pri()
{
for(int i=;i<=;++i)
{
if(!v[i])
{
pp[++cnt]=i;
}
for(int j=;j<=cnt&&i*pp[j]<=;++j)
{
v[i*pp[j]]=;
if(i%pp[j]==)break;
}
}
}
ll calc(ll n,ll m,ll p)
{
ll ans=;
for(ll x=p,i=;i<=cnt&&x;++i)
{
if(x==)break;
if(x%pp[i]==)
{
ll num=;
while(x%pp[i]==)x/=pp[i],num*=pp[i];
ans=(ans+C(n,m,p,pp[i],num))%p;
}
}
return ans;
}
ll F(ll x,ll p)
{
ll ans=;
if(x==)return ;
x=x%(*p);
if(x==)x=*p;
for(int i=;i<=x;++i)
ans=(ans*i+(i%==?:-))%p;
return (ans+p)%p;
}
int main()
{
ll n,m,p,t,ans=;
scanf("%I64d",&t);pri();v[]=;
for(int ii=;ii<=t;++ii)
{
scanf("%I64d%I64d%I64d",&n,&m,&p);
ans=calc(n,m,p)%p;
ans=ans*F(n-m,p)%p;
printf("Case %d: %I64d\n",ii,ans);
}
return ;
}

再补个我的辣鸡程序,路过的dalao帮忙看看也中啊、

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll qmod(ll n,ll m,ll p)
{
ll ans=;
while(m)
{
if(m&)ans=ans*n%p;
n=n*n%p;m>>=;
}
return ans;
}
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b){
x=;y=;return;
}
exgcd(b,a%b,y,x);y-=a/b*x;
}
ll inv(ll n,ll p)
{
if(!n)return ;
ll a=n,b=p,x=,y=;
exgcd(a,b,x,y);
x=(x%b+b)%b;
if(!x)x+=b;
return x;
}
ll mul(ll n,ll pi,ll pk)
{
if(!n)return 1ll;
ll ans=;
if(n/pk)
{
for(ll i=;i<=pk;++i)
if(i%pi)ans=ans*i%pk;
ans=qmod(ans,n/pk,pk)%pk;
}
for(ll i=;i<=n%pk;++i)
if(i%pi)ans=ans*i%pk;
return ans*mul(n/pi,pi,pk)%pk;
}
int C(ll n,ll m,ll p,ll pi,ll pk)
{
if(m>n)return ;
ll a=mul(n,pi,pk),b=mul(m,pi,pk),c=mul(n-m,pi,pk);
ll k=,ans;
for(ll i=n;i;i/=pi)k+=i/pi;
for(ll i=m;i;i/=pi)k-=i/pi;
for(ll i=n-m;i;i/=pi)k-=i/pi;
ans=a*inv(b,pk)%pk*inv(c,pk)%pk*qmod(pi,k,pk)%pk;
return ans*(p/pk)%p*inv(p/pk,pk)%p;//CRT
}
bool v[];
int pp[],cnt;
void pri()
{
for(int i=;i<=;++i)
{
if(!v[i])
{
pp[++cnt]=i;
}
for(int j=;j<=cnt&&i*pp[j]<=;++j)
{
v[i*pp[j]]=;
if(i%pp[j]==)break;
}
}
}
ll calc(ll n,ll m,ll p)
{
ll ans=;
for(ll x=p,i=;i<=cnt&&x;++i)
{
if(x==)break;
if(x%pp[i]==)
{
ll num=;
while(x%pp[i]==)x/=pp[i],num*=pp[i];
ans=(ans+C(n,m,p,pp[i],num))%p;
}
}
return ans;
}
int main()
{
ll n,m,p,t,ans=;
scanf("%I64d",&t);pri();v[]=;
for(int ii=;ii<=t;++ii)
{
scanf("%I64d%I64d%I64d",&n,&m,&p);
ans=calc(n,m,p)%p;n-=m;ll pre=;ll num=,pos=max(0ll,n-p);
if(!ans)
{
printf("Case %d: %I64d\n",ii,pre*ans%p);continue;
}
for(ll k=n;k>=pos;--k)
{
if(n!=k)num=num*(n-k)%p;
if(k&1ll)pre=(pre-calc(n,k,p)%p*num%p+p)%p;
else pre=(pre+calc(n,k,p)%p*num%p)%p;
if(!num)break;
}
printf("Case %d: %I64d\n",ii,pre*ans%p);
}
return ;
}

好吧,蒟蒻苦逼的一下午。

同时纪念衡水人民224起义。

HDU3439 Sequence的更多相关文章

  1. [SPOJ SEQN] [hdu3439]Sequence

    题目就是求C(n,k)*H(n - k)%m 0<= k<= n <=10^9, 1 <= m <= 10^5, n != 0 其中H(n)是错排第n项. 对于C(n,k ...

  2. oracle SEQUENCE 创建, 修改,删除

    oracle创建序列化: CREATE SEQUENCE seq_itv_collection            INCREMENT BY 1  -- 每次加几个              STA ...

  3. Oracle数据库自动备份SQL文本:Procedure存储过程,View视图,Function函数,Trigger触发器,Sequence序列号等

    功能:备份存储过程,视图,函数触发器,Sequence序列号等准备工作:--1.创建文件夹 :'E:/OracleBackUp/ProcBack';--文本存放的路径--2.执行:create or ...

  4. DG gap sequence修复一例

    环境:Oracle 11.2.0.4 DG 故障现象: 客户在备库告警日志中发现GAP sequence提示信息: Mon Nov 21 09:53:29 2016 Media Recovery Wa ...

  5. Permutation Sequence

    The set [1,2,3,-,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

  6. [LeetCode] Sequence Reconstruction 序列重建

    Check whether the original sequence org can be uniquely reconstructed from the sequences in seqs. Th ...

  7. [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列

    Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...

  8. [LeetCode] Verify Preorder Sequence in Binary Search Tree 验证二叉搜索树的先序序列

    Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary ...

  9. [LeetCode] Longest Consecutive Sequence 求最长连续序列

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...

随机推荐

  1. Vue单页面应用阻止浏览器记住密码

    Vue单页面应用阻止浏览器记住密码 ——IT唐伯虎 摘要: Vue单页面应用阻止浏览器记住密码. 现象1:路由切换时再次提示“是否记住密码” 登录页面有个密码输入框,输入账号密码进行登录: 登录完成后 ...

  2. 转:Xcode打印堆栈信息

    2#   分享于 14-11-26 19:15:36 Chrome 39.0.2171.71 Mac OS X 10.10.1 如果只是看调用栈的话,可以使用 lldb 的功能.在你的代码里面打上一个 ...

  3. Javascript加速运动与减速运动

    加速运动,即一个物体运动时速度越来越快:减速运动,即一个物体运动时速度越来越慢.现在用Javascript来模拟这两个效果,原理就是用setInterval或setTimeout动态改变一个元素与另外 ...

  4. git的权威指南

    CHENYILONG 博客 git的权威指南 全屏 © chenyilong.本站由Postach.io 博客

  5. CString 与其它数据类型转换问题

    CString 头文件#include <afx.h> string 头文件#include <string.h> CString 转char * CString cstr; ...

  6. zabbix user parameters和Loadable modules的使用方法介绍

    目录 需求 实现 原理 前端配置 后端配置 shell实现 python实现 C实现 需求: 采集主机的-/+ buffers/cache  free的数据 实现: 采集/proc/meminfo中的 ...

  7. rpmbuild 构建rpm包时报错解决 error: Installed (but unpackaged) file(s) found:

    解决的办法是找到 /usr/lib/rpm/macros 中%__check_files         /usr/lib/rpm/check-files %{buildroot}   注释掉

  8. arm GIC介绍之四【转】

    转自:https://blog.csdn.net/sunsissy/article/details/73882718 GIC是ARM体系中重要的组件,在认识到GIC的组成和功能之后,了解到IRQ的大致 ...

  9. Linux DRM KMS 驱动简介【转】

    转自:https://blog.csdn.net/yangkuanqaz85988/article/details/48689521 Whoops,上次写完<Linux DRM Graphic ...

  10. 【坐在马桶上看算法】算法7:Dijkstra最短路算法

           上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”.本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径 ...