题解:

网上的做法好像都是容斥

那就先说一下容斥

首先问题等价于求下面这个式子的方案数

$$\sum_{i=1}^{n} ai (0<ai<i) =k$$

直接$dp$复杂度是$nk$的,无法接受

我们考虑容斥

答案=所有-至少1个不满足+至少2个不满足-....

而不满足等价于$ai>=i$ 那么我们只需要令$b[i]=a[i]-i$就可以与其他等价了

实际上这样子看上去这个容斥并没有用处

因为要$dp$出容斥系数看上去至少是$O(n^2)$

现在我们需要算出,用i个不相同的数相加=k的方案数

我们注意一件事情,i的取值只有$\sqrt{k}$,所以如果状态设计得好,是可以的

要求数不同有一个经典套路就是 把操作转化成

1.给当前数组内全体数+1

2.给当前数组内全体数+1再在末尾放一个1

于是$f[i][j]$表示数组内有i个数,和为j的方案数 $$f[i][j]=f[i-1][j-i]+f[i][j-i]$$复杂度$n\sqrt{n}$

然后你写一下,肯定会发现出问题了(我没写这种做法但下面这种的时候遇到了同样的问题)

因为这么做可能有数>n了

怎么保证没有数>n呢,我们只需要令每个时刻的$f[i][j]$都是<=n的

那么出现大于n的只可能是n+1,$f[i][j]-=f[i-1][j-n-1]$就可以了

还是比较难想的。。

这题还有个做法是生成函数,在思维上就简单很多

$$f(x)=\frac{\prod_{i=1}^{n} (1-x^i)}{(1-x)^n}$$

然后要求这个东西,暴力是n^2logn的

然后乘法比较显然的是两边取ln,得到

$$ln(f(x))=\sum_{i=1}^{n} {ln(1-x^i)} - n*ln(1-x)$$

这样子我们发现要解决的就是$ln(1-x^i)$

这个东西就两项但我们要用$nlogn$的多项式求逆是不是太浪费了

于是打表找规律,可以发现(不过要是不知道结论考场谁有时间去打个多项式求ln找规律啊。。)

$ln(1-x)=\frac{1}{1}x+\frac{1}{2}x^2+\frac{1}{3}x^3+...$

$ln(1-x^2)=\frac{1}{1}x^2+\frac{1}{2}x^4+\frac{1}{3}x^6+...$

下面的规律同理

于是我们可以利用筛法在$nlogn$时间内求出

当然由于$$f(x)=\sum {d|x} {}{ \ \ \ g1(d)g2(\frac{x}{d}) }$$ 其中$g1(i)=\frac{1}{i},g2(i)=1$

因为$g1(i),g2(i)$是完全积性函数(只要是积性就可以了),所以他们的卷积也是积性函数

所以可以用线性筛做到$O(n)$ 我们类似于做约数和再维护一个h(i)表示不包括i的最小素因子的g1的和

于是就是多项式exp模板题了

  1. #pragma GCC optimize(2)
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. #define rint register int
  5. #define IL inline
  6. #define rep(i,h,t) for(int i=h;i<=t;i++)
  7. #define dep(i,t,h) for(int i=t;i>=h;i--)
  8. #define ll long long
  9. #define me(x) memset(x,0,sizeof(x))
  10. #define mep(x,y) memcpy(x,y,sizeof(y))
  11. #define mid (t<=0?(h+t-1)/2:(h+t)/2)
  12. namespace IO{
  13. char ss[<<],*A=ss,*B=ss;
  14. IL char gc()
  15. {
  16. return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;
  17. }
  18. template<class T> void read(T &x)
  19. {
  20. rint f=,c; while (c=gc(),c<||c>) if (c=='-') f=-; x=(c^);
  21. while (c=gc(),c>&&c<) x=(x<<)+(x<<)+(c^); x*=f;
  22. }
  23. char sr[<<],z[]; ll Z,C1=-;
  24. template<class T>void wer(T x)
  25. {
  26. if (x<) sr[++C1]='-',x=-x;
  27. while (z[++Z]=x%+,x/=);
  28. while (sr[++C1]=z[Z],--Z);
  29. }
  30. IL void wer1()
  31. {
  32. sr[++C1]=' ';
  33. }
  34. IL void wer2()
  35. {
  36. sr[++C1]='\n';
  37. }
  38. template<class T>IL void maxa(T &x,T y) {if (x<y) x=y;}
  39. template<class T>IL void mina(T &x,T y) {if (x>y) x=y;}
  40. template<class T>IL T MAX(T x,T y){return x>y?x:y;}
  41. template<class T>IL T MIN(T x,T y){return x<y?x:y;}
  42. };
  43. using namespace IO;
  44. const double ee=1.00000000000000;
  45. const double pi=acos(-1.0);
  46. const int N=4e5+;
  47. const int mo=1e9+;
  48. int r[N],n,m,l,inv[N],n1[N],n2[N];
  49. struct cp{
  50. double a,b;
  51. IL cp operator +(const cp &o) const
  52. {
  53. return (cp){a+o.a,b+o.b};
  54. }
  55. IL cp operator -(const cp &o) const
  56. {
  57. return (cp){a-o.a,b-o.b};
  58. }
  59. IL cp operator *(register const cp &o) const
  60. {
  61. return (cp){a*o.a-b*o.b,o.a*b+o.b*a};
  62. }
  63. }a[N],b[N],c[N],d[N];
  64. IL int fsp(int x,int y)
  65. {
  66. ll now=;
  67. while (y)
  68. {
  69. if (y&) now=now*x%mo;
  70. x=1ll*x*x%mo;
  71. y>>=;
  72. }
  73. return now;
  74. }
  75. IL void clear()
  76. {
  77. for (int i=;i<=n;i++) a[i].a=a[i].b=b[i].a=b[i].b=c[i].a=c[i].b=d[i].a=d[i].b=;
  78. }
  79. cp *w[N],tmp[N*];
  80. int p;
  81. IL void init()
  82. {
  83. cp *now=tmp;
  84. for (int i=;i<=p;i<<=)
  85. {
  86. w[i]=now;
  87. for (int j=;j<i;j++) w[i][j]=(cp){cos(pi*j/i),sin(pi*j/i)};
  88. now+=i;
  89. }
  90. }
  91. IL void fft_init()
  92. {
  93. l=; for (n=;n<=m;n<<=) l++;
  94. for (int i=;i<n;i++) r[i]=(r[i/]/)|((i&)<<(l-));
  95. }
  96. void fft(cp *a,int o)
  97. {
  98. for (int i=;i<n;i++) if (i>r[i]) swap(a[i],a[r[i]]);
  99. for (int i=;i<n;i<<=)
  100. for (int j=;j<n;j+=(i*))
  101. {
  102. cp *x1=a+j,*x2=a+i+j,*W=w[i];
  103. for (int k=;k<i;k++,x1++,x2++,W++)
  104. {
  105. cp x=*x1,y=(cp){(*W).a,(*W).b*o}*(*x2);
  106. *x1=x+y,*x2=x-y;
  107. }
  108. }
  109. if (o==-) for(int i=;i<n;i++) a[i].a/=n;
  110. }
  111. IL void getcj(int *A,int *B,int len)
  112. {
  113. rep(i,,len)
  114. {
  115. A[i]=(A[i]+mo)%mo,B[i]=(B[i]+mo)%mo;
  116. }
  117. for (int i=;i<len;i++)
  118. {
  119. a[i]=(cp){A[i]&,A[i]>>};
  120. b[i]=(cp){B[i]&,B[i]>>};
  121. }
  122. m=len*; fft_init();
  123. fft(a,); fft(b,);
  124. for (int i=;i<n;i++)
  125. {
  126. int j=(n-)&(n-i);
  127. c[j]=(cp){0.5*(a[i].a+a[j].a),0.5*(a[i].b-a[j].b)}*b[i];
  128. d[j]=(cp){0.5*(a[i].b+a[j].b),0.5*(a[j].a-a[i].a)}*b[i];
  129. }
  130. fft(c,); fft(d,);
  131. double inv=ee/n;
  132. rep(i,,n) c[i].a*=inv,c[i].b*=inv;
  133. rep(i,,n) d[i].a*=inv,d[i].b*=inv;
  134. rep(i,,len)
  135. {
  136. ll a1=c[i].a+0.5,a2=c[i].b+0.5;
  137. ll a3=d[i].a+0.5,a4=d[i].b+0.5;
  138. B[i]=(a1+((a2+a3)%mo<<)+((a4%mo)<<))%mo;
  139. }
  140. clear();
  141. }
  142. void getinv(int *A,int *B,int len)
  143. {
  144. if (len==) { B[]=fsp(A[],mo-); return;};
  145. getinv(A,B,(len+)/);
  146. int C[N]={};
  147. rep(i,,len-) C[i]=A[i];
  148. getcj(B,C,len);
  149. getcj(B,C,len);
  150. for (int i=;i<len;i++) B[i]=((2ll*B[i]-C[i])%mo+mo)%mo;
  151. }
  152. IL void getDao(int *a,int *b,int len)
  153. {
  154. for (int i=;i<len;i++) b[i-]=1ll*i*a[i]%mo;
  155. b[len-]=;
  156. }
  157. IL void getjf(int *a,int *b,int len)
  158. {
  159. for (int i=;i<len;i++) b[i+]=1ll*a[i]*inv[i+]%mo;
  160. b[]=;
  161. }
  162. IL void getln(int *A,int *B,int len)
  163. {
  164. int C[N]={},D[N]={};
  165. getDao(A,C,len);
  166. getinv(A,D,len);
  167. getcj(C,D,len);
  168. getjf(D,B,len);
  169. }
  170. IL void getexp(int *A,int *B,int len)
  171. {
  172. if (len==) {B[]=; return;}
  173. getexp(A,B,(len+)>>);
  174. int C[N]={};
  175. getln(B,C,len);
  176. for(int i=;i<len;i++) C[i]=(-C[i]+A[i])%mo;
  177. C[]=(C[]+)%mo;
  178. getcj(C,B,len);
  179. }
  180. int main()
  181. {
  182. freopen("1.in","r",stdin);
  183. freopen("1.out","w",stdout);
  184. inv[]=;
  185. rep(i,,1e5+) inv[i]=(1ll*inv[mo%i]*(mo-(mo/i)))%mo;
  186. int n,k;
  187. read(n); read(k); k++;
  188. n1[]=; n1[]=-;
  189. p=k<<;
  190. init();
  191. getln(n1,n2,k);
  192. rep(i,,k) n1[i]=-1ll*n*n2[i]%mo;
  193. rep(i,,n)
  194. {
  195. for(int j=;j*i<=k;j++)
  196. (n1[i*j]-=inv[j])%=mo;
  197. }
  198. me(n2);
  199. getexp(n1,n2,k);
  200. cout<<(n2[k-]+mo)%mo<<endl;
  201. return ;
  202. }

loj6077的更多相关文章

  1. 【LOJ6077】「2017 山东一轮集训 Day7」逆序对 生成函数+组合数+DP

    [LOJ6077]「2017 山东一轮集训 Day7」逆序对 题目描述 给定 n,k ,请求出长度为 n的逆序对数恰好为 k 的排列的个数.答案对 109+7 取模. 对于一个长度为 n 的排列 p ...

  2. loj6077. 「2017 山东一轮集训 Day7」逆序对

    题目描述: loj 题解: 容斥+生成函数. 考虑加入的第$i$个元素对结果的贡献是$[0,i-1]$,我们可以列出生成函数. 长这样:$(1)*(1+x)*(1+x+x^2)*--*(1+x+x^2 ...

  3. LOJ6077「2017 山东一轮集训 Day7」逆序对 (生成函数+多项式exp?朴素DP!)

    题面 给定 n , k n,k n,k ,求长度为 n n n 逆序对个数为 k k k 的排列个数,对 1 e 9 + 7 \rm1e9+7 1e9+7 取模. 1 ≤ n , k ≤ 100   ...

  4. 8月清北学堂培训 Day3

    今天是赵和旭老师的讲授~ 状态压缩 dp 状态压缩是设计 dp 状态的一种方式. 当普通的 dp 状态维数很多(或者说维数与输入数据有关),但每一维总量很少时,可以将多维状态压缩为一维来记录. 这种题 ...

  5. DP&图论 DAY 3 上午

    DP&图论  DAY 3  上午 状态压缩dp >状态压缩dp ◦状态压缩是设计dp状态的一种方式.◦当普通的dp状态维数很多(或者说维数与输入数据有关),但每一维总量很少是,可以将多维 ...

随机推荐

  1. 4.ansible的delegate_to

    完成发布流程如下 first 修改nginx 配置文件下线 web1-2 使用 delegate_to 将默认hosts指定为 nginx主机 使用remote_user 将用户 锁定为 root s ...

  2. js实现一键导出Excel

    演示地址:https://xibushijie.github.io/static/ExportToExcel.html <!DOCTYPE html> <html lang=&quo ...

  3. 11.4 Flask session,闪现

    session 加密后放在用户浏览器的 cookie 中 于django 的自带session 不同,flask 的 session 需要导入 from flask import session 添加 ...

  4. NetSarang软件中nssock2.dll模块被植入恶意代码技术分析与防护方案

    原文地址:http://blog.nsfocus.net/nssock2-dll-module-malicious-code-analysis-report/ NetSarang是一家提供安全连接解决 ...

  5. Mybatis的应用2 使用mybits+SpringBoot完成第一个查询的demo(随后加增加,更新,删除)

    首先在mapper下面新建一个mysql.xml mysql.xml <?xml version="1.0" encoding="UTF-8" ?> ...

  6. halcon+WinForm显示rgb图并灰度化

    1.halcon代码,并导出成C# read_image (Demo, 'C:/Users/user/Pictures/demo.jpg') dev_display (Demo) rgb1_to_gr ...

  7. SNMP学习——v3 VACM

    目录: ☆ SNMPv3视图访问控制模型    ☆ SNMPv3报文格式    ☆ VACM参数    ☆ Context Table    ☆ Security To Group Table     ...

  8. Deepin linux 远程桌面无法被Ubuntu连接

    linux下远程桌面的工具还是有很多的,这个方法主要是解决Ubuntu自带的 Remmina无法远程 Deepin 桌面. 1.安装vncserver的基础服务,输入以下命令: sudo apt-ge ...

  9. BFC块级格式化上下文

    BFC块级格式化上下文 触发条件 overflow 值不为 visible 的块元素 根元素 html 元素 浮动元素(元素的 float 不是 none) 绝对定位元素(元素的 position 为 ...

  10. 第九节:从源码的角度分析MVC中的一些特性及其用法

    一. 前世今生 乍眼一看,该标题写的有点煽情,最近也是在不断反思,怎么能把博客写好,让人能读下去,通俗易懂,深入浅出. 接下来几个章节都是围绕框架本身提供特性展开,有MVC程序集提供的,也有其它程序集 ...