题面

题面

题解

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

首先我们发现,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. Flask开发环境搭建

    基础准备 Python 3.6.5 Conda Visual Studio Code 虚拟环境 创建虚拟环境 conda create -n flask 激活虚拟环境 activate flask 关 ...

  2. js中对象转化成字符串、数字或布尔值的转化规则

    js中对象可以转化成 字符串.数字.布尔值 一.对象转化成字符串: 规则: 1.如果对象有toString方法,则调用该方法,并返回相应的结果:(代码通常会执行到这,因为在所有对象中都有toStrin ...

  3. 车牌,车架号,VIN码毫秒识别技术,汽车后市场的春天到来了

    vin码(车架号)识别运用 不仅在制造.销售.保养.保险.车辆评估.交易环节会需要录入汽车的VIN码,在交通事故处理中,作为汽车身份唯一识别码,VIN码是处理事故的执法人员必须要记录的信息之一.随着汽 ...

  4. 使用Photon引擎进行unity网络游戏开发(三)——网络游戏大厅及房间

    使用Photon引擎进行unity网络游戏开发(三)--网络游戏大厅及房间 Photon PUN Unity 网络游戏开发 连接到Photon ConnectUsingSettings 设置你的客户端 ...

  5. 《图解 HTTP 》阅读 —— 第二章

    第2章 简单的http协议 http 协议用于客户端和服务器端的通信. 请求访问文本或图像等资源的一端称为客户端,提供资源响应的一端称为服务器端. 请求报文: 响应报文: 为了能够处理大量的事务,ht ...

  6. mysqldb下载地址

    mysqldb x64    https://pan.baidu.com/s/1dFJ3G0T x32及源码 https://pypi.python.org/pypi/MySQL-python/1.2 ...

  7. 关于js中一个对象当做参数传递是按值传递还是按引用传递的个人看法

    在<JavaScript高级程序设计>这本书中有这样一段话:有很多开发人员错误的认为:在局部作用域中修改的对象会在全局作用域中反映出来,就说明参数是按引用传递的.换句话说,尼古拉认为当一个 ...

  8. 20181016-4 Alpha阶段第1周/共2周 Scrum立会报告+燃尽图 02

    此次作业要求参见 [https://edu.cnblogs.com/campus/nenu/2018fall/homework/2247] Scrum master:祁玉 一.小组介绍 组长:王一可 ...

  9. 软件工程-东北师大站-第四次作业PSP

    1.本周PSP 2.本周进度条 3.本周累计进度图 代码累计折线图 博文字数累计折线图 4.本周PSP饼状图

  10. 查看dll依赖项

    win7 系统: 开始-->所有程序->vs2012文件夹->vs tools->对应的命令提示符 输入命令: dumpbin /dependents 你的文件(可以是exe, ...