题目:给定一个1到n的排列,求字典序小于这个排列的所有排列的逆序对数之和。

思路:既然是求字典序小于这个排列的,不妨将排列根据和它前k位相同来分类,然后枚举第k+1位的数(小于原序列第k+1位的数),假设逆序对的位置为(x,y),对于1<=x<k+1,x<y<=k+1和1<=x<=k+1,k+2<=y<=n的答案是容易计算出来的,对于k+2<=x<n,x<y<=n的答案则可以通过dp来计算由于剩余的数已没有大小意义了,假设剩余p个不同的数,则p个数的全排列产生的逆序对总数与1-p这p个数产生的全排列的逆序对总数是相同的,所以可以令dp[n]表示n个数产生的全排列的逆序对总数,则dp[n] =dp[n-1]*n+C(n,2)*(n-1)!。

  1. #pragma comment(linker, "/STACK:10240000,10240000")
  2.  
  3. #include <iostream>
  4. #include <cstdio>
  5. #include <algorithm>
  6. #include <cstdlib>
  7. #include <cstring>
  8. #include <map>
  9. #include <queue>
  10. #include <deque>
  11. #include <cmath>
  12. #include <vector>
  13. #include <ctime>
  14. #include <cctype>
  15. #include <set>
  16. #include <bitset>
  17. #include <functional>
  18. #include <numeric>
  19. #include <stdexcept>
  20. #include <utility>
  21.  
  22. using namespace std;
  23.  
  24. #define mem0(a) memset(a, 0, sizeof(a))
  25. #define mem_1(a) memset(a, -1, sizeof(a))
  26. #define lson l, m, rt << 1
  27. #define rson m + 1, r, rt << 1 | 1
  28. #define define_m int m = (l + r) >> 1
  29. #define rep_up0(a, b) for (int a = 0; a < (b); a++)
  30. #define rep_up1(a, b) for (int a = 1; a <= (b); a++)
  31. #define rep_down0(a, b) for (int a = b - 1; a >= 0; a--)
  32. #define rep_down1(a, b) for (int a = b; a > 0; a--)
  33. #define all(a) (a).begin(), (a).end()
  34. #define lowbit(x) ((x) & (-(x)))
  35. #define constructInt4(name, a, b, c, d) name(int a = 0, int b = 0, int c = 0, int d = 0): a(a), b(b), c(c), d(d) {}
  36. #define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
  37. #define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
  38. #define pchr(a) putchar(a)
  39. #define pstr(a) printf("%s", a)
  40. #define sstr(a) scanf("%s", a)
  41. #define sint(a) scanf("%d", &a)
  42. #define sint2(a, b) scanf("%d%d", &a, &b)
  43. #define sint3(a, b, c) scanf("%d%d%d", &a, &b, &c)
  44. #define pint(a) printf("%d\n", a)
  45. #define test_print1(a) cout << "var1 = " << a << endl
  46. #define test_print2(a, b) cout << "var1 = " << a << ", var2 = " << b << endl
  47. #define test_print3(a, b, c) cout << "var1 = " << a << ", var2 = " << b << ", var3 = " << c << endl
  48. #define mp(a, b) make_pair(a, b)
  49. #define pb(a) push_back(a)
  50.  
  51. typedef unsigned int uint;
  52. typedef long long LL;
  53. typedef pair<int, int> pii;
  54. typedef vector<int> vi;
  55.  
  56. const int dx[] = {, , -, , , , -, -};
  57. const int dy[] = {-, , , , , -, , - };
  58. const int maxn = 1e8 + ;
  59. const int md = 1e9 + ;
  60. const int inf = 1e9 + ;
  61. const LL inf_L = 1e18 + ;
  62. const double pi = acos(-1.0);
  63. const double eps = 1e-;
  64.  
  65. template<class T>T gcd(T a, T b){return b==?a:gcd(b,a%b);}
  66. template<class T>bool max_update(T &a,const T &b){if(b>a){a = b; return true;}return false;}
  67. template<class T>bool min_update(T &a,const T &b){if(b<a){a = b; return true;}return false;}
  68. template<class T>T condition(bool f, T a, T b){return f?a:b;}
  69. template<class T>void copy_arr(T a[], T b[], int n){rep_up0(i,n)a[i]=b[i];}
  70. int make_id(int x, int y, int n) { return x * n + y; }
  71.  
  72. template<int mod>
  73. struct ModInt {
  74. const static int MD = mod;
  75. int x;
  76. ModInt(int x = ): x(x) { if (x < ) x += mod; }
  77. int get() { return x; }
  78.  
  79. ModInt operator + (const ModInt &that) const { int x0 = x + that.x; return ModInt(x0 < MD? x0 : x0 - MD); }
  80. ModInt operator - (const ModInt &that) const { int x0 = x - that.x; return ModInt(x0 < MD? x0 + MD : x0); }
  81. ModInt operator * (const ModInt &that) const { return ModInt((long long)x * that.x % MD); }
  82. ModInt operator / (const ModInt &that) const { return *this * that.inverse(); }
  83.  
  84. ModInt operator += (const ModInt &that) { x += that.x; if (x >= MD) x -= MD; }
  85. ModInt operator -= (const ModInt &that) { x -= that.x; if (x < ) x += MD; }
  86. ModInt operator *= (const ModInt &that) { x = (long long)x * that.x % MD; }
  87. ModInt operator /= (const ModInt &that) { *this = *this / that; }
  88.  
  89. ModInt inverse() const {
  90. int a = x, b = MD, u = , v = ;
  91. while(b) {
  92. int t = a / b;
  93. a -= t * b; std::swap(a, b);
  94. u -= t * v; std::swap(u, v);
  95. }
  96. if(u < ) u += MD;
  97. return u;
  98. }
  99.  
  100. };
  101. typedef ModInt<md> mint;
  102. mint dp[], fact[];
  103. int n, a[];
  104. bool vis[];
  105.  
  106. void init() {
  107. fact[] = ;
  108. rep_up1(i, ) {
  109. dp[i] = dp[i - ] * i + fact[i - ] * i * (i - ) / ;
  110. fact[i] = fact[i - ] * i;
  111. }
  112. }
  113.  
  114. int main() {
  115. //freopen("in.txt", "r", stdin);
  116. init();
  117. while (cin >> n) {
  118. rep_up0(i, n) sint(a[i]);
  119. mem0(vis);
  120. mint ans = ;
  121. rep_up0(i, n) {
  122. int c = ;
  123. rep_up0(j, i) {
  124. for (int k = j + ; k < i; k ++) {
  125. if (a[j] > a[k]) c ++;
  126. }
  127. }
  128. rep_up1(j, a[i] - ) {
  129. if (!vis[j]) {
  130. ans += fact[n - i - ] * c;
  131. rep_up0(k, i) {
  132. if (a[k] > j) ans += fact[n - i - ];
  133. }
  134. int sum = ;
  135. vis[j] = true;
  136. rep_up1(k, n) {
  137. if (!vis[k]) sum ++;
  138. else ans += fact[n - i - ] * sum;
  139. }
  140. ans += dp[n - i - ];
  141. vis[j] =false;
  142. }
  143. }
  144. vis[a[i]] = true;
  145. }
  146. cout << ans.get() << endl;
  147. }
  148. return ;
  149. }

[hdu5225]逆序对统计的更多相关文章

  1. 51nod1779 逆序对统计

    1779 逆序对统计 基准时间限制:1 秒 空间限制:131072 KB  lyk最近计划按顺序做n道题目,每道题目都分为很多分数档次,lyk觉得这些题太简单了,于是它想到了一个好玩的游戏. lyk决 ...

  2. UVA 11858 Frosh Week 逆序对统计

    题目链接: http://acm.hust.edu.cn/vjudge/contest/122094#problem/H Frosh Week Time Limit:8000MSMemory Limi ...

  3. 51nod 1779逆序对统计(状压DP)

    按照插入数的大小排序, 然后依次进行dp. 用一个状态表示n个数是否被选了 10110 就是表示第1.3.4个位置都选了 那么如果此时这个数该填到5这个位置,那么必定会造成一个逆序(因为下一个数会填到 ...

  4. SPOJ COWPIC(逆序对变形题)

    SPOJ COWPIC 题目链接 题意:一个序列,相邻能够交换.问最少交换几次使得变成循环的1-n的当中一种 思路:对于原来正常的变换成1-n而言,答案就是逆序对了,而多了这么一个变形,事实上仅仅须要 ...

  5. 逆序对 -- cogs1438 火柴排队

    题目链接:http://cogs.pro:8081/cogs/problem/problem.php?pid=vimiQkqjU [题目描述] 样例一输入: 4 2 3 1 4 3 2 1 4 样例二 ...

  6. 【CQOI2011】动态逆序对 BZOJ3295

    Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...

  7. BZOJ 3295: [Cqoi2011]动态逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3865  Solved: 1298[Submit][Sta ...

  8. BZOJ 3295 【Cqoi2011】 动态逆序对

    Description 对于序列\(A\),它的逆序对数定义为满足\(i<j\),且\(A_i>A_j\)的数对\((i,j)\)的个数.给\(1\)到\(n\)的一个排列,按照某种顺序依 ...

  9. 【bzoj3295】 Cqoi2011—动态逆序对

    http://www.lydsy.com/JudgeOnline/problem.php?id=3295 (题目链接) 题意 给出某种排列,按照某种顺序依次删除m个数,在每次删除一个数前统计序列中逆序 ...

随机推荐

  1. [Abp vNext 入坑分享] - 2.简化项目结构

    一.简要说明 本篇文章根据我自己的需要对项目结果进行简化,让项目结构更符合我自己的要求,同时让项目跑起来.仅供参考 二.具体步骤 2.1卸载掉对我来说目前使用不上的项目,identityserver, ...

  2. Unity ML-agents 一、初次尝试

    前言 曾在高二寒假的时候,跟表哥在外面玩,当时他问我有没有想过以后要做什么,我愣了一下,回答不上来.是的,从没想过以后要做什么,只是一直在完成学校.老师安排的任务,于是那之后半年,我一直在思考,大学要 ...

  3. Vulnhub-dpwwn-01靶机过关记录

    靶机地址:172.16.1.192 Kali 目录扫描 查看info.php 端口扫描 开放3306,尝试弱密码或爆破mysql. 账户为root,密码为空,成功登陆. 查看数据库:再查看ssh表 查 ...

  4. Vue 3.0 Composition API - 中文翻译

    Composition API 发布转载请附原文链接 https://www.cnblogs.com/zgh-blog/articles/composition_api.html 这两天初步了解了下 ...

  5. 一篇文章掌握网页解析神器——xpath

    学爬虫不会xpath解析数据? 今天老师带你一堂课带你从零开始精通xpath,从此轻松提取网页信息. 我们在爬虫的过程中,经常会遇到html字符串数据,很多我们需要的数据不是作为标签的文本就是作标签的 ...

  6. discuz-目录

    由于工作原因,开始学习discuz,0基础开发,学了一会总结了一些

  7. python学习02python入门二

    学前须知:1.本文档有关内容均建立在python3.x版本上,python2.x已经成为历史,如有需要,文内会特别说明. 2.本文使用的编辑器多为架构在Windows上的pycharm,如需了解Lin ...

  8. [Inno Setup] 卸载 重启之后 删除文件

    某些系统文件,例如驱动,不重启无法删除. 利用windows注册表里的 RunOnce.注意必须在HKLM下,否则可能权限不够. 不能直接填cmd命令,要以cmd的参数形式填写. procedure ...

  9. Deep Snake : 基于轮廓调整的SOTA实例分割方法,速度32.3fps | CVPR 2020

    论文提出基于轮廓的实例分割方法Deep snake,轮廓调整是个很不错的方向,引入循环卷积,不仅提升了性能还减少了计算量,保持了实时性,但是Deep snake的大体结构不够优雅,应该还有一些工作可以 ...

  10. (转)SQLite数据库的加密

    1.创建空的SQLite数据库. //数据库名的后缀你可以直接指定,甚至没有后缀都可以 //方法一:创建一个空sqlite数据库,用IO的方式 FileStream fs = File.Create( ...