[JZOJ5135][SDOI省队集训2017]逆序对
来源:互联网 发布:淘宝优惠券群是真的吗 编辑:程序博客网 时间:2024/06/04 19:36
题目大意
有多少n的排列逆序对个数为k?
模型转化
假设有一个i的排列,插入i+1逆序对个数会增加多少?
发现会增加0~i。
因此模型转化为,n个变量,
问有多少x序列,满足和为k。
生成函数意义
把第i个的生成函数写出来。
定义
那么
FFT做法
我们知道
因此可以用调和级数即n log n复杂度内求出ln F(x)。
接着用FFT做多项式的exp。
本题模数比较诡异,要用毛爷爷FFT。
DP做法
好好学过生成函数都知道
因此
后面就是个组合数,因此想办法求出前面的部分。
观察它的组合意义:
有n个物品,第i个物品大小为i。
假如选了j个物品,大小和为n,会贡献(-1)^j。
就是个带符号的连续背包问题!
我们考虑代入经典DP,设f[i,j]表示i个数和为j的贡献和。
想象有i个数递增的排列着。
第一种情况,全部+1。
那么f[i][j]+=f[i-1][j-i]
第二种情况,全部+1,再在最前面添加一个1。
那么f[i][j]-=f[i-1][j-i](带符号所以这里是减号)
上面这两种情况可以造出任意互不相同的一堆递增数。
但是注意可能最大的那个会超出n,因此要除掉,有
f[i][j]+=f[i-1][j-(n+1)](带符号所以这里是加号)
于是就行了。
容斥意义
考虑容斥意义,注意我们对n个变量x有限制。
第i个限制是xi<=i-1。
我们考虑容斥,枚举至少哪些条件不满足。
例如第i个条件不满足,那么xi>=i,我们将总和减去i即变成了xi>=0。
因此考虑这个意义也能得到生成函数意义下最后需要解决的问题。
#include<cstdio>#include<algorithm>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)#define fd(i,a,b) for(i=a;i>=b;i--)using namespace std;typedef long long ll;const int maxn=100000+10,maxs=450+10,mo=1000000007;int f[maxs][maxn],fac[maxn*2],inv[maxn*2];int i,j,k,l,t,n,m,s,ans;int qsm(int x,int y){ if (!y) return 1; int t=qsm(x,y/2); t=(ll)t*t%mo; if (y%2) t=(ll)t*x%mo; return t;}int C(int n,int m){ if (n<m||m<0) return 0; return (ll)fac[n]*inv[m]%mo*inv[n-m]%mo;}int main(){ freopen("inverse.in","r",stdin);freopen("inverse.out","w",stdout); scanf("%d%d",&n,&k); fac[0]=1; fo(i,1,n+k) fac[i]=(ll)fac[i-1]*i%mo; inv[n+k]=qsm(fac[n+k],mo-2); fd(i,n+k-1,0) inv[i]=(ll)inv[i+1]*(i+1)%mo; //s=floor(sqrt(k))+1; s=450; f[0][0]=1; fo(i,1,s) fo(j,0,k){ if (j>=i) (f[i][j]-=f[i-1][j-i])%=mo; if (j>=i) (f[i][j]+=f[i][j-i])%=mo; if (j>=n+1) (f[i][j]+=f[i-1][j-(n+1)])%=mo; } fo(i,0,k){ t=0; fo(j,0,s) (t+=f[j][i])%=mo; (ans+=(ll)t*C(k-i+n-1,n-1)%mo)%=mo; } (ans+=mo)%=mo; printf("%d\n",ans);}
- [JZOJ5135][SDOI省队集训2017]逆序对
- [bzoj4927][SDOI省队集训2017]diyiti
- [bzoj4928][SDOI省队集训2017]dierti
- [bzoj4930][SDOI省队集训2017]棋盘
- [bzoj4931][SDOI省队集训2017]塔
- [JZOJ5129][SDOI省队集训2017]字符串
- [JZOJ5133][SDOI省队集训2017]重建
- [JZOJ5136][SDOI省队集训2017]重排
- [JZOJ5131][SDOI省队集训2017]距离
- [JZOJ5130][51nod1446][SDOI省队集训2017]苹果树
- [JZOJ5132][SDOI省队集训2017]子序列
- [JZOJ5134][SDOI省队集训2017]三元组
- [JZOJ5137][SDOI省队集训2017][bzoj4842]养猫
- [JZOJ5135]逆序对/[HackerRank-101hack43]K-Inversion Permutations
- 【SDOI省队集训题】棋盘(最小费用流)
- 【SDOI省队集训题】pair(线段树+二分)
- LOJ #6077. 「2017 山东一轮集训 Day7」逆序对
- LOJ #6077. 「2017 山东一轮集训 Day7」逆序对
- PAT (Advanced Level) Practise 1109 Group Photo (25)
- 排序算法
- Updating a Dictionary
- nodejs学习(一)读文件,写文件,文件信息
- jq 添加元素
- [JZOJ5135][SDOI省队集训2017]逆序对
- 页面自动执行(加载)js的几种方法
- ZJOI2005独木舟上的旅行
- c++用户界面编程
- Cmake如何编译Qt程序
- Spring Bean的作用域
- 在浏览器中输入www.baidu.com后执行的全部过程
- Android TP驱动之(二)设备树解析
- 概念笔记