1. 题目描述
$A[i]$表示二级制表示的$i$的数字之和。求$1 \le i < j \le n$并且$A[i]>A[j]$的$(i,j)$的总对数。

2. 基本思路
$n \le 10^300$。$n$这么大,显然只能用数位DP来做,我们可以预先处理一下将$n$表示成二进制,然后再进行DP。
$dp[i][j][k]$表示长度为i,两者$A$的差为$j$,状态为$k$的总数。
不妨令$|n| = l$,因此$j \in [-l, l]$,因此需要$+l$,将$j$映射到$[0,l*2]$上。
在考虑$k$有多少种情况?不妨令$(x,y), x<y$表示一对可行解。
(0) $Pref(x) < Pref(y), Pref(y) < Pref(n)$;
(1) $Pref(x) < Pref(y), Pref(y) == Pref(n)$;
(2) $Pref(x) == Pref(y), Pref(y) < Pref(n)$;
(3) $Pref(x) == Pref(y), Pref(y) == Pref(n)$;
上面4中情况分别对应$k \in [0, 3]$,剩下的就是状态转移就好了,还是挺简单的。总对数就是
\[\sum_{j = l+1}^{l*2}{dp[l][j][0]+dp[l][j][1]}\]
可以使用滚动数组优化,其实也可以不使用。

3. 代码

  1. /* 5632 */
  2. #include <iostream>
  3. #include <sstream>
  4. #include <string>
  5. #include <map>
  6. #include <queue>
  7. #include <set>
  8. #include <stack>
  9. #include <vector>
  10. #include <deque>
  11. #include <bitset>
  12. #include <algorithm>
  13. #include <cstdio>
  14. #include <cmath>
  15. #include <ctime>
  16. #include <cstring>
  17. #include <climits>
  18. #include <cctype>
  19. #include <cassert>
  20. #include <functional>
  21. #include <iterator>
  22. #include <iomanip>
  23. using namespace std;
  24. //#pragma comment(linker,"/STACK:102400000,1024000")
  25.  
  26. #define sti set<int>
  27. #define stpii set<pair<int, int> >
  28. #define mpii map<int,int>
  29. #define vi vector<int>
  30. #define pii pair<int,int>
  31. #define vpii vector<pair<int,int> >
  32. #define rep(i, a, n) for (int i=a;i<n;++i)
  33. #define per(i, a, n) for (int i=n-1;i>=a;--i)
  34. #define clr clear
  35. #define pb push_back
  36. #define mp make_pair
  37. #define fir first
  38. #define sec second
  39. #define all(x) (x).begin(),(x).end()
  40. #define SZ(x) ((int)(x).size())
  41. #define lson l, mid, rt<<1
  42. #define rson mid+1, r, rt<<1|1
  43.  
  44. const int mod = ;
  45. const int maxl = ;
  46. const int maxn = ;
  47. char ss[maxl];
  48. int a[maxn];
  49. int dp[][maxn<<][];
  50.  
  51. void solve() {
  52. int l = , tmp;
  53. int len = strlen(ss);
  54.  
  55. rep(i, , len)
  56. ss[i] -= '';
  57.  
  58. int b = ;
  59.  
  60. while (b<len && ss[b]==)
  61. ++b;
  62. if (b >= len) {
  63. puts("");
  64. return ;
  65. }
  66.  
  67. while () {
  68. a[l++] = ss[len-] & ;
  69. tmp = ;
  70. rep(i, b, len) {
  71. if (ss[i] & ) {
  72. ss[i] = (tmp+ss[i])>>;
  73. tmp = ;
  74. } else {
  75. ss[i] = (tmp+ss[i])>>;
  76. tmp = ;
  77. }
  78. }
  79. while (b<len && ss[b]==)
  80. ++b;
  81. if (b >= len)
  82. break;
  83. }
  84.  
  85. reverse(a, a+l);
  86.  
  87. int l2 = l + l;
  88. int p = , q = ;
  89.  
  90. memset(dp, , sizeof(dp));
  91.  
  92. rep(ii, , a[]+) {
  93. rep(jj, , a[]+) {
  94. if (ii > jj)
  95. continue;
  96.  
  97. int nj = ii - jj + l;
  98. int nk = (ii==jj) ? (jj==a[])| : (jj==a[]);
  99. ++dp[p][nj][nk];
  100. }
  101. }
  102.  
  103. rep(i, , l) {
  104. rep(j, , l2+) {
  105. // i < j
  106. rep(k, , ) {
  107. if (!dp[p][j][k])
  108. continue;
  109.  
  110. int mn1, mn2, nj, nk;
  111.  
  112. mn1 = ;
  113. mn2 = (k&) ? a[i]:;
  114.  
  115. rep(ii, , mn1+) {
  116. rep(jj, , mn2+) {
  117. nj = j + ii - jj;
  118. nk = (k==) && (jj==a[i]);
  119. if (nj >= )
  120. dp[q][nj][nk] = (dp[q][nj][nk] + dp[p][j][k]) % mod;
  121. }
  122. }
  123. }
  124. // i = j
  125. rep(k, , ) {
  126. if (!dp[p][j][k])
  127. continue;
  128.  
  129. int mn, nj, nk;
  130.  
  131. mn = (k&) ? a[i]:;
  132. rep(ii, , mn+) {
  133. rep(jj, , mn+) {
  134. if (ii > jj)
  135. continue;
  136.  
  137. nj = j + (ii==) - (jj==);
  138. if (k == ) {
  139. nk = (ii<jj) ? :;
  140. } else {
  141. nk = (ii<jj) ? (jj==a[i]) : (jj==a[i])|;
  142. }
  143. if (nj >= )
  144. dp[q][nj][nk] = (dp[q][nj][nk] + dp[p][j][k]) % mod;
  145. }
  146. }
  147. }
  148. }
  149. p ^= ;
  150. q ^= ;
  151. memset(dp[q], , sizeof(dp[q]));
  152. }
  153.  
  154. int ans = ;
  155.  
  156. rep(j, l+, l2+)
  157. rep(k, , )
  158. ans = (ans + dp[p][j][k]) % mod;
  159.  
  160. printf("%d\n", ans);
  161. }
  162.  
  163. int main() {
  164. ios::sync_with_stdio(false);
  165. #ifndef ONLINE_JUDGE
  166. freopen("data.in", "r", stdin);
  167. freopen("data.out", "w", stdout);
  168. #endif
  169.  
  170. int t;
  171.  
  172. scanf("%d", &t);
  173. while (t--) {
  174. scanf("%s", ss);
  175. solve();
  176. }
  177.  
  178. #ifndef ONLINE_JUDGE
  179. printf("time = %d.\n", (int)clock());
  180. #endif
  181.  
  182. return ;
  183. }

4. 数据生成器

  1. import sys
  2. import string
  3. from random import randint, shuffle
  4.  
  5. def GenData(fileName):
  6. with open(fileName, "w") as fout:
  7. t = 10
  8. fout.write("%d\n" % (t))
  9. ld = string.digits
  10. for tt in xrange(t):
  11. length = randint(200, 300)
  12. L = [0] * length
  13. for i in xrange(length):
  14. L[i] = randint(0, 9)
  15. L[0] = randint(1, 9)
  16. fout.write("".join(map(str, L)) + "\n")
  17.  
  18. def MovData(srcFileName, desFileName):
  19. with open(srcFileName, "r") as fin:
  20. lines = fin.readlines()
  21. with open(desFileName, "w") as fout:
  22. fout.write("".join(lines))
  23.  
  24. def CompData():
  25. print "comp"
  26. srcFileName = "F:\Qt_prj\hdoj\data.out"
  27. desFileName = "F:\workspace\cpp_hdoj\data.out"
  28. srcLines = []
  29. desLines = []
  30. with open(srcFileName, "r") as fin:
  31. srcLines = fin.readlines()
  32. with open(desFileName, "r") as fin:
  33. desLines = fin.readlines()
  34. n = min(len(srcLines), len(desLines))-1
  35. for i in xrange(n):
  36. ans2 = int(desLines[i])
  37. ans1 = int(srcLines[i])
  38. if ans1 > ans2:
  39. print "%d: wrong" % i
  40.  
  41. if __name__ == "__main__":
  42. srcFileName = "F:\Qt_prj\hdoj\data.in"
  43. desFileName = "F:\workspace\cpp_hdoj\data.in"
  44. GenData(srcFileName)
  45. MovData(srcFileName, desFileName)

【HDOJ】5632 Rikka with Array的更多相关文章

  1. 【HDOJ】5203 Rikka with wood sticks

    /* 1002 */ #include <iostream> #include <string> #include <map> #include <queue ...

  2. 【转】python之模块array

    [转]python之模块array >>> import array#定义了一种序列数据结构 >>> help(array) #创建数组,相当于初始化一个数组,如: ...

  3. 【题解】[CF718C Sasha and Array]

    [题解]CF718C Sasha and Array 对于我这种喜欢写结构体封装起来的选手这道题真是太对胃了\(hhh\) 一句话题解:直接开一颗线段树的矩阵然后暴力维护还要卡卡常数 我们来把\(2 ...

  4. 【LeetCode】数组-6(561)-Array Partition I(比较抽象的题目)

    题目描述:两句话发人深思啊.... Given an array of 2n integers, your task is to group these integers into n pairs o ...

  5. 【VBA】利用Range声明Array(一维/二维)

    [说明] B2开始到B?(中间不能有空格),定义一维数组Arr_approver() Dim R_sh As Worksheet Set R_sh = ThisWorkbook.Sheets(&quo ...

  6. 【HDOJ】4729 An Easy Problem for Elfness

    其实是求树上的路径间的数据第K大的题目.果断主席树 + LCA.初始流量是这条路径上的最小值.若a<=b,显然直接为s->t建立pipe可以使流量最优:否则,对[0, 10**4]二分得到 ...

  7. 【HDOJ】【3506】Monkey Party

    DP/四边形不等式 裸题环形石子合并…… 拆环为链即可 //HDOJ 3506 #include<cmath> #include<vector> #include<cst ...

  8. 【HDOJ】【3516】Tree Construction

    DP/四边形不等式 这题跟石子合并有点像…… dp[i][j]为将第 i 个点开始的 j 个点合并的最小代价. 易知有 dp[i][j]=min{dp[i][j] , dp[i][k-i+1]+dp[ ...

  9. 【HDOJ】【3480】Division

    DP/四边形不等式 要求将一个可重集S分成M个子集,求子集的极差的平方和最小是多少…… 首先我们先将这N个数排序,容易想到每个自己都对应着这个有序数组中的一段……而不会是互相穿插着= =因为交换一下明 ...

随机推荐

  1. Linux内核分析作业一

    一.实验 通过反汇编一个简单的c语言程序来分析计算机是如何工作的 1.进入实验楼,在实验楼环境下把c语言代码转换成汇编码 汇编代码如下图: 二.汇编代码的工作过程中堆栈的变化:(手绘步骤,顺序是从左到 ...

  2. 小王子浅读Effective javascript(一)了解javascript版本

    哈哈,各位园友新年快乐!愚安好久没在园子里写东西了,这次决定针对javascript做一个系列,叫做<小王子浅读Effective javascript>,主要是按照David Herma ...

  3. 【转】android 内存泄漏相关收藏博客。

    关于android内存泄漏的研究   博客建了几个月,都没有去写,一是因为当时换工作,然后又是新入职(你懂的,好好表现),比较忙:二是也因为自己没有写博客的习惯了.现在还算是比较稳定了,加上这个迭代基 ...

  4. EntityFrame6在本地可以正常使用,部署到IIS后报异常(Additional information: The underlying provider failed on Open.)

    异常详细:An exception of type 'System.Data.Entity.Core.EntityException' occurred in EntityFramework.SqlS ...

  5. IntelliJ IDEA 15 显示工具栏及底部周边工具栏

  6. SpringJUnit4测试--测试无反应/控制台报空指针的解决---junit的jar冲突!

    前言: 前些日子碰到一个诡异的问题--用springJUnit进行测试,运行方法什么反应也没有,控制台 也没有输出,百度也没有答案--只好暂时作罢.今天我只好用上了排除法,建个测试小项目,将只要能测试 ...

  7. linux文件系统创建文件的过程

    创建一个文件最主要的步骤就是: 1.为文件创建一个文件目录项. 2.为文件创建一个inode结构并分配inode号,将inode编号与文件名映射关系保存在1中分配的文件目录项中. 3.将1中创建的文件 ...

  8. HDOJ 3547 DIY Cube 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3547 题目大意:求用$C$种颜色给立方体的8个顶点染色的本质不同的方法.两种方法本质不同即不能通过旋转 ...

  9. Unity3D之Vector3.Dot和Vector3.Cross的使用

    在unity3d中,Vector3.Dot表示求两个向量的点积;Vector3.Cross表示求两个向量的叉积. 点积计算的结果为数值,而叉积计算的结果为向量.两者要注意区别开来. 在几何数学中: 1 ...

  10. Unity3D研究院之打开Activity与调用JAVA代码传递参数

    原地址:http://www.xuanyusong.com/archives/667    Unity for Android 比较特殊,Unity for IOS 打包是将XCODE工程直接交给开发 ...