题面

题面

题解

(表示第一段文字导致我在考场上没看懂题……因为我以为这个定义是定义在整个排列上的,所以相似 = 相同。结果其实是可以应用在一个区间上……)

首先我们发现,2个区间相似,其实就是离散化之后相同。

观察到,相似区间的位置是没有影响的,且由于数字两两不同,所以不管相似区间内是哪些数,我们都可以将其当做一个1 ~ len的排列来计算。

因此我们可以直接枚举相似区间的长度和逆序对个数,然后按照从小到大的顺序加入下一个数,DP出方案,也就是区间个数。

设f[i][j]表示长度为i,逆序对恰好j个方案数。

因为新插入的i严格大于1 ~ i - 1,所以插入x带来的新逆序对个数为0 ~ i - 1,因此有:

\[f[i][j] = \sum_{k = j - i + 1}^{j} f[i - 1][k]
\]

因此用前缀和优化一下就可以同时做到快速转移 + 逆序对至多j。

然后对于每次询问,我们枚举一下区间长度,用组合数和阶乘算一下区间放不同数字和区间放在不同位置的方案数,求和输出即可。

注意一个坑点,排列有2个,所以组合数和阶乘都要乘2次……

#include<bits/stdc++.h>
using namespace std;
#define R register int
#define LL long long
#define AC 510
#define ac 130100
#define p 1000000007
#define maxn 500 int T, n, m, ans;
int f[AC][ac], C[AC][AC], fac[AC]; inline int read()
{
int x = 0;char c = getchar();
while(c > '9' || c < '0') c = getchar();
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x;
} inline void upmin(int &a, int b) {if(b < a) a = b;}
inline void upmax(int &a, int b) {if(b > a) a = b;}
inline void up(int &a, int b) {a += b; if(a >= p) a -= p;}
inline int ad(int a, int b) {return ((a + b) % p + p) % p;}
inline int mul(int a, int b) {return 1LL * a * b % p;}
inline int two(int x) {return 1LL * x * x % p;}//因为有2个排列,所以组合数和阶乘都要乘2次 void get()
{
for(R i = 0; i <= maxn; i ++) C[i][0] = 1;
for(R i = 1; i <= maxn; i ++)
for(R j = 1; j <= maxn; j ++)
up(C[i][j], C[i - 1][j - 1]), up(C[i][j], C[i - 1][j]);
fac[0] = fac[1] = 1;
for(R i = 2; i <= maxn; i ++) fac[i] = mul(fac[i - 1], i);
} void build()
{
for(R i = 0; i <= maxn; i ++) f[i][0] = 1;//初始化
for(R i = 1; i <= maxn; i ++)//枚举数的个数
{//f[i][j] = \sum_{k = j - i + 1}^{j}{f[i - 1][k]}相当于恰好转移到恰好,而后面的sum部分就是至多,我们所需要的也是至多
int all = (i - 1) * i / 2, tmp = maxn * maxn / 2;//所以转移的时候顺便求一下前缀和就好了
for(R j = 1; j <= tmp; j ++)//枚举逆序对的个数,因为是至多j个,所以>all的也要枚举
{//因为插入第i个数最多产生i - 1的贡献,所以还需要减去一些东西(k <= j - i就不合法了,凑不到i个逆序对)
if(j <= all) f[i][j] = ad(f[i - 1][j], (j - i >= 0) ? - f[i - 1][j - i] : 0);
up(f[i][j], f[i][j - 1]);
}
}
} void work()
{
T = read();
while(T --)
{
n = read(), m = read(), ans = 0, m = min(n * n / 2, m);//对这个取min!因为前面的DP数组只统计到这了
for(R i = 1; i <= n; i ++)
up(ans, mul(mul(mul(f[i][m], two(C[n][i])), two(fac[n - i])), (n - i + 1)));
printf("%d\n", (ans + p) % p);
}
} int main()
{
// freopen("in.in", "r", stdin);
get();
build();
work();
// fclose(stdin);
return 0;
}

[FJWC2018]全排列 DP的更多相关文章

  1. [FJWC2018]全排列

    题解: 考虑长度为k的时候的贡献 即取出一些元素然后给他们排个顺序然后问你有多少排法 假设排法为ans 那么应该就是$C(n,k)*C(n,k)*(n-k)!*(n-k)!*(n-k+1)*ans$ ...

  2. 山东省第五届ACM省赛

    题目链接:http://acm.sdut.edu.cn/sdutoj/contest_show.php?contest_id=1449 相关总结:http://www.cnblogs.com/mcfl ...

  3. 多校7 HDU5816 Hearthstone 状压DP+全排列

    多校7 HDU5816 Hearthstone 状压DP+全排列 题意:boss的PH为p,n张A牌,m张B牌.抽取一张牌,能胜利的概率是多少? 如果抽到的是A牌,当剩余牌的数目不少于2张,再从剩余牌 ...

  4. 子矩阵(暴搜(全排列)+DP)

    子矩阵(暴搜(全排列)+DP) 一.题目 子矩阵 时间限制: 1 Sec  内存限制: 128 MB 提交: 1  解决: 1 [提交][状态][讨论版] 题目描述 给出如下定义: 1. 子矩阵:从一 ...

  5. hdu 1069 (DP) Monkey and Banana

    题目:这里 题意: Description 一组研究人员正在设计一项实验,以测试猴子的智商.他们将挂香蕉在建筑物的屋顶,同时,提供一些砖块给这些猴子.如果猴子足够聪明,它应当能够通过合理的放置一些砖块 ...

  6. 【DP】组合数字

    Password Attacker 题意就是给 M 个关键字,组合成 N 字符长度的结果,每一个关键字都必须在 N 位的字符中出现,有多少种可能结果. 范围 1 ≤ M ≤ N ≤ 100. 举例假设 ...

  7. HDU5816 Hearthstone(状压DP)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5816 Description Hearthstone is an online collec ...

  8. loj 1021(状压dp+记忆化搜索)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25887 题目大意:给定的一个某进制下的排列,问它的全排列有多少个能 ...

  9. LightOJ1158 Anagram Division(状压DP)

    题目问一个数字字符串的不重复全排列有几个能被d整除. dp[S][m]表示用字符集合S构成的%d为m的数字字符串个数 dp[0][0]=0 我为人人转移,dp[S+{x}][(m*10+str[x]- ...

随机推荐

  1. 五、Django之路由系统

    1.普通路由匹配 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表:它就是以这种方式告诉Django,用哪个URL调用 ...

  2. git远程版本回滚方法【转】

    step1:本地代码回滚到上一版本(或者指定版本) git reset --hard HEAD~1 step2:加入-f参数,强制提交,远程端将强制跟新到reset版本 git push -f ori ...

  3. php 操作 oracle lob 数据2

    CREATE SEQUENCE mylobs_id_seq    NOMINVALUE    NOMAXVALUE    NOCYCLE    CACHE 20    NOORDERINCREMENT ...

  4. iOS开发之多线程技术—GCD篇

    本篇将从四个方面对iOS开发中GCD的使用进行详尽的讲解: 一.什么是GCD 二.我们为什么要用GCD技术 三.在实际开发中如何使用GCD更好的实现我们的需求 一.Synchronous & ...

  5. Hyperledger Fabric CouchDB as the State Database——使用CouchDB

    使用CouchDB作为状态数据库 状态数据库选项 状态数据库包括LevelDB和CouchDB.LevelDB是嵌入在peer进程中的默认键/值状态数据库,CouchDB是一个可选的外部状态数据库.与 ...

  6. Hyperledger Fabric 1.1 -- Policy 构成

    Policy 规则设计 本文主要是讲解一下在fabric中Policy的规则和写法,让大家有一个初步的认识,本文是基于fabric 1.1版本 Policy Type Policy Type 目前包括 ...

  7. Zabbix部署-LNMP环境

    原文发表于cu:2016-05-05 参考文档: LNMP安装:http://www.osyunwei.com/archives/7891.html 一.环境 Server:CentOS-7-x86_ ...

  8. 【Shell 开发】Shell 目录

    目录 [第一章]Shell 概述 [第二章]Shell 变量 [第三章]Shell 变量的数值计算 [第四章]Shell 条件测试表达式 [shell 练习1]编写Shell条件句练习 [shell ...

  9. [python] Queue.Queue vs. collections.deque

    https://stackoverflow.com/questions/717148/queue-queue-vs-collections-deque/717199#717199 Queue,Queu ...

  10. 20181120-10 Beta阶段第2周/共2周 Scrum立会报告+燃尽图 7

    此作业要求参见:[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2415] 版本控制地址    [https://git.coding.n ...