JZOJ 5598 全排列
2018-03-24 14:34
281 查看
传送门
考场上的思路
参考代码
总结
传送门
考场上的思路
差一点就对了……样例太坑爹……
枚举区间的长度 ll,则对于长度 ll 在排列中有 n−l+1n−l+1 个可选位置。考虑对答案的贡献,当我们确定了排列 aa 的区间的元素时,我们可以直接计算排列 bb 对答案的贡献。假设 aa 的区间中的元素确定了,那么 bb 对答案的贡献就是 Cln∗(n−l)!Cnl∗(n−l)!。再考虑 aa 中长度为 ll 的区间有多少个(要满足逆序对需求),不难发现 EE 的范围是假的,最大也只有 n(n−1)2n(n−1)2,因此可以设 fi,jfi,j 表示长度为 ii 且逆序数小于等于 jjj 的排列个数,可以 O(n3)O(n3) 转移。考试时可以先考虑逆序数恰好为 jj 的排列,最后来求前缀和,发现转移正好可以利用前缀和转移,然后就 O(n3)O(n3) 了。
因此对于 aa 区间长度为 ll 的区间个数为 Cln×(n−l)!×fl,min(E,n(n−1)2)Cnl×(n−l)!×fl,min(E,n(n−1)2),把它和之前 bb 对答案的贡献乘起来就好了(因为互相独立)。
参考代码
总结
考试时就是忘了还要考虑区间外的元素对答案的贡献(×(n−l)!×(n−l)!),然后就爆零了。考试时也没有发现可以直接用前缀和转移,还以为是个卷积要用任意模数 NTT QAQ。
以后要对拍了……不打暴力还是不稳啊,T1 暴力错了也是蛮拼的。
考场上的思路
参考代码
总结
传送门
考场上的思路
差一点就对了……样例太坑爹……
枚举区间的长度 ll,则对于长度 ll 在排列中有 n−l+1n−l+1 个可选位置。考虑对答案的贡献,当我们确定了排列 aa 的区间的元素时,我们可以直接计算排列 bb 对答案的贡献。假设 aa 的区间中的元素确定了,那么 bb 对答案的贡献就是 Cln∗(n−l)!Cnl∗(n−l)!。再考虑 aa 中长度为 ll 的区间有多少个(要满足逆序对需求),不难发现 EE 的范围是假的,最大也只有 n(n−1)2n(n−1)2,因此可以设 fi,jfi,j 表示长度为 ii 且逆序数小于等于 jjj 的排列个数,可以 O(n3)O(n3) 转移。考试时可以先考虑逆序数恰好为 jj 的排列,最后来求前缀和,发现转移正好可以利用前缀和转移,然后就 O(n3)O(n3) 了。
因此对于 aa 区间长度为 ll 的区间个数为 Cln×(n−l)!×fl,min(E,n(n−1)2)Cnl×(n−l)!×fl,min(E,n(n−1)2),把它和之前 bb 对答案的贡献乘起来就好了(因为互相独立)。
参考代码
#include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <cassert> #include <cctype> #include <climits> #include <ctime> #include <iostream> #include <algorithm> #include <vector> #include <string> #include <stack> #include <queue> #include <deque> #include <map> #include <set> #include <bitset> #include <list> #include <functional> typedef long long LL; typedef unsigned long long ULL; using std::cin; using std::cout; using std::endl; typedef int INT_PUT; INT_PUT readIn() { INT_PUT a = 0; bool positive = true; char ch = getchar(); while (!(ch == '-' || std::isdigit(ch))) ch = getchar(); if (ch == '-') { positive = false; ch = getchar(); } while (std::isdigit(ch)) { a = a * 10 - (ch - '0'); ch = getchar(); } if (positive) a = -a; return a; } void printOut(INT_PUT x) { char buffer[20]; int length = 0; if (x < 0) putchar('-'); else x = -x; do buffer[length++] = -(x % 10) + '0'; while (x /= 10); do putchar(buffer[--length]); while (length); putchar('\n'); } const int mod = int(1e9) + 7; const int maxn = 505; const int maxto = 500; const int maxe = maxto * (maxto - 1) / 2; int f[maxn][maxn * maxn / 2]; int C[maxn][maxn]; int fac[maxn]; void init() { C[0][0] = 1; for (register int i = 1; i <= maxto; i++) { C[i][0] = 1; for (register int j = 1; j <= i; j++) { int temp; C[i][j] = (temp = C[i - 1][j - 1] + C[i - 1][j]) >= mod ? temp - mod : temp; } } for (register int i = 0; i <= maxe; i++) f[1][i] = 1; for (register int i = 2; i <= maxto; i++) { for (register int j = 0, to = i * (i - 1) / 2; j <= to; j++) { f[i][j] = ((LL)f[i][j] + f[i - 1][j] - (j - i >= 0 ? f[i - 1][j - i] : 0) + mod) % mod; // 直接利用前缀和转移 } for (register int j = 1; j <= maxe; j++) { register int temp; f[i][j] = (temp = f[i][j] + f[i][j - 1]) >= mod ? temp - mod : temp; } } fac[0] = 1; for (int i = 1; i <= maxto; i++) fac[i] = (LL)fac[i - 1] * i % mod; } int n, E; void run() { init(); int T = readIn(); while (T--) { n = readIn(); E = std::min(readIn(), n * (n - 1) / 2); LL ans = 0; for (register int i = 1; i <= n; i++) ans = (ans + (LL)fac[n - i] * fac[n - i] % mod * (n - i + 1) % mod * f[i][E] % mod * C [i] % mod * C [i] % mod) % mod; printOut(ans); } } int main() { #ifndef LOCAL freopen("perm.in", "r", stdin); freopen("perm.out", "w", stdout); #endif run(); return 0; }
总结
考试时就是忘了还要考虑区间外的元素对答案的贡献(×(n−l)!×(n−l)!),然后就爆零了。考试时也没有发现可以直接用前缀和转移,还以为是个卷积要用任意模数 NTT QAQ。
以后要对拍了……不打暴力还是不稳啊,T1 暴力错了也是蛮拼的。
相关文章推荐
- JZOJ 5253. 排列与交换
- 排列统计 jzoj 1283
- Jzoj5429 排列
- jzoj3775 因子的排列
- JZOJ 3775. 【NOIP2014模拟8.15】因子的排列
- 【JZOJ 5429】【NOIP2017提高A组集训10.27】排列
- JZOJ 5235. 【NOIP2017模拟8.7A组】好的排列
- [JZOJ5429]【NOIP2017提高A组集训10.27】排列
- JZOJ5235. 【NOIP2017模拟8.7A组】好的排列
- JZOJ 5429 排列
- JZOJ3232. 【佛山市选2013】排列
- [排序][dp][二分]JZOJ 2746 选数排列
- jzoj3775 [NOIP2014模拟8.15]因子的排列
- Jzoj3163 排列
- JZOJ 3775. 【NOIP2014模拟8.15】因子的排列
- [置顶] 【JZOJ5429】【NOIP2017提高A组集训10.27】排列
- 【bzoj 3622】【JZOJ 5429】 排列
- jzoj 2746.【2012中山市选】选数排列(pick) 二分答案+dp
- 学习排列组合总结
- 有重复元素的全排列问题