码迷,mamicode.com
首页 > 其他好文 > 详细

dp 容斥 bzoj3622 已经没有什么好害怕的了

时间:2018-07-07 13:52:14      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:const   sum   problem   void   code   ret   temp   typename   typeof   

https://www.lydsy.com/JudgeOnline/problem.php?id=3622

XJOI题 不过没做过。。

容斥计数啊

先排序

\(f[i][j]\)为前\(i\)位有\(j\)位固定且\(a[j] > b[k]\)的方案数

\[f[i][j] = f[i - 1][j] + f[i - 1][j - 1] \times (last - (j - 1))\]

\(last\)为最大的\(k\)使得\(a[i] > b[k]\)

\[f[n][i] = \sum_{k=i}^{n}ans[k] \binom{k}{i}\]

这部分是容斥

然后\(\mathcal O(n ^ 2)\)暴力维护就好了

感觉好套路

#include <bits/stdc++.h>
#define int long long
#define rint register int
#define fo(i, n) for(rint i = 1; i <= (n); i ++)
#define out(x) cerr << #x << " = " << x << "\n"
#define type(x) __typeof((x).begin())
#define foreach(it, x) for(type(x) it = (x).begin(); it != (x).end(); ++ it)
using namespace std;
// by piano
template<typename tp> inline void read(tp &x) {
  x = 0;char c = getchar(); bool f = 0;
  for(; c < '0' || c > '9'; f |= (c == '-'), c = getchar());
  for(; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar());
  if(f) x = -x;
}
const int mo = 1e9 + 9;
const int N = 2333;
int n, K;
int c[N][N], fac[N], f[N][N], ans[N], nxt[N], a[N], b[N];
main(void) {
  read(n); read(K);
  if((n - K) & 1) return puts("0"), 0;
  K = n - (n - K) / 2;
  for(int i = 0; i <= n; i ++)
    c[i][0] = 1;
  for(int i = 1; i <= n; i ++)
    for(int j = 1; j <= n; j ++)
      c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mo;
  fac[0] = 1;
  for(int i = 1; i <= n; i ++)
    fac[i] = fac[i - 1] * i % mo;
  for(int i = 1; i <= n; i ++) read(a[i]);
  for(int i = 1; i <= n; i ++) read(b[i]);
  sort(a + 1, a + n + 1); sort(b + 1, b + n + 1);
  for(int i = 1; i <= n; i ++) {
    for(int k = 1; k <= n; k ++)
      if(a[i] > b[k])
        nxt[i] = k;
  }
  f[0][0] = 1;
  for(int i = 1; i <= n; i ++) {
    for(int j = 0; j <= n; j ++) {
      f[i][j] = f[i - 1][j];
      if(j && nxt[i] - (j - 1) > 0) f[i][j] = (f[i][j] + f[i - 1][j - 1] * (nxt[i] - (j - 1)) % mo) % mo;
    }
  }
  for(int j = 0; j <= n; j ++)
    ans[j] = f[n][j] * fac[n - j] % mo;
   
  for(int j = n - 1; j >= 0; j --) {
    for(int i = j + 1; i <= n; i ++)
      ans[j] = (ans[j] - ans[i] * c[i][j] % mo + mo) % mo;
  }
  cout << ans[K] << "\n";
}

dp 容斥 bzoj3622 已经没有什么好害怕的了

标签:const   sum   problem   void   code   ret   temp   typename   typeof   

原文地址:https://www.cnblogs.com/foreverpiano/p/9276839.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!