题面

题面

题解

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

首先我们发现,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. cdh中hdfs非ha环境迁移Namenode与secondaryNamenode,从uc机器到阿里;

    1.停掉外部接入服务: 2 NameNode Metadata备份: 2.1 备份fsimage数据,(该操作适用HA和非HA的NameNode),使用如下命令进行备份: [root@cdh01 df ...

  2. 说说ejabberd 离线消息的坑

    使用过ejabberd的或许知道,也许踩过这个坑.那么就说说我们踩过的ejabberd的离线消息的坑吧. ejabberd原生的离线消息的机制是,一般用户保存100条离线消息,管理员保存5000条离线 ...

  3. [转载]A cycle was detected in the build path of project

    解决Eclipse中Java工程间循环引用而报错的问题 如果我们的项目包含多个工程(project),而它们之间又是循环引用的关系,那么Eclipse在编译时会抛出如下一个错误信息: “A cycle ...

  4. 理解学习Springboot(二)

    一.关闭banner 如果不想看到任何的banner,可以将其关闭. 当然也可以自己自定义banner,http://patorjk.com/software/taag/#p=display& ...

  5. TPO-18 C2 Possible participation in a sociology project

    TPO-18 C2 Possible participation in a sociology project 第 1 段 1.listen to a conversation between a s ...

  6. Unity中几个特殊路径在各个平台的访问方式

    1.文件路径Resources:Unity在发布成移动端项目后,其他文件路径都将不存在,但是如果有一些必要的资源,可以放在Resources文件夹下,因为这个文件夹下的所有资源是由Unity内部进行调 ...

  7. python程序设计——面向对象程序设计:继承

    继承是为代码复用和设计复用而设计的 在继承关系中,已有的.设计好的类称为父类或基类,新设计的类为子类或派生类 派生类可以继承父类的公有成员,但不能继承其私有成员 如果需要在派生类中调用基类的方法,可以 ...

  8. 简述AQS原理

    这是一道面试题:简述AQS原理 AQS核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态.如果被请求的共享资源被占用,那么就需要一套线程阻塞 ...

  9. 第五章—if语句

    5-1 条件测试 :编写一系列条件测试:将每个测试以及你对其结果的预测和实际结果都打印出来.你编写的代码应类似于下面这样: car = 'subaru' print("Is car == ' ...

  10. Python 数据图表工具的比较

    Python 的科学栈相当成熟,各种应用场景都有相关的模块,包括机器学习和数据分析.数据可视化是发现数据和展示结果的重要一环,只不过过去以来,相对于 R 这样的工具,发展还是落后一些. 幸运的是,过去 ...