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. 代码

 /* 5632 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <bitset>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 const int mod = ;
const int maxl = ;
const int maxn = ;
char ss[maxl];
int a[maxn];
int dp[][maxn<<][]; void solve() {
int l = , tmp;
int len = strlen(ss); rep(i, , len)
ss[i] -= ''; int b = ; while (b<len && ss[b]==)
++b;
if (b >= len) {
puts("");
return ;
} while () {
a[l++] = ss[len-] & ;
tmp = ;
rep(i, b, len) {
if (ss[i] & ) {
ss[i] = (tmp+ss[i])>>;
tmp = ;
} else {
ss[i] = (tmp+ss[i])>>;
tmp = ;
}
}
while (b<len && ss[b]==)
++b;
if (b >= len)
break;
} reverse(a, a+l); int l2 = l + l;
int p = , q = ; memset(dp, , sizeof(dp)); rep(ii, , a[]+) {
rep(jj, , a[]+) {
if (ii > jj)
continue; int nj = ii - jj + l;
int nk = (ii==jj) ? (jj==a[])| : (jj==a[]);
++dp[p][nj][nk];
}
} rep(i, , l) {
rep(j, , l2+) {
// i < j
rep(k, , ) {
if (!dp[p][j][k])
continue; int mn1, mn2, nj, nk; mn1 = ;
mn2 = (k&) ? a[i]:; rep(ii, , mn1+) {
rep(jj, , mn2+) {
nj = j + ii - jj;
nk = (k==) && (jj==a[i]);
if (nj >= )
dp[q][nj][nk] = (dp[q][nj][nk] + dp[p][j][k]) % mod;
}
}
}
// i = j
rep(k, , ) {
if (!dp[p][j][k])
continue; int mn, nj, nk; mn = (k&) ? a[i]:;
rep(ii, , mn+) {
rep(jj, , mn+) {
if (ii > jj)
continue; nj = j + (ii==) - (jj==);
if (k == ) {
nk = (ii<jj) ? :;
} else {
nk = (ii<jj) ? (jj==a[i]) : (jj==a[i])|;
}
if (nj >= )
dp[q][nj][nk] = (dp[q][nj][nk] + dp[p][j][k]) % mod;
}
}
}
}
p ^= ;
q ^= ;
memset(dp[q], , sizeof(dp[q]));
} int ans = ; rep(j, l+, l2+)
rep(k, , )
ans = (ans + dp[p][j][k]) % mod; printf("%d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int t; scanf("%d", &t);
while (t--) {
scanf("%s", ss);
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

4. 数据生成器

 import sys
import string
from random import randint, shuffle def GenData(fileName):
with open(fileName, "w") as fout:
t = 10
fout.write("%d\n" % (t))
ld = string.digits
for tt in xrange(t):
length = randint(200, 300)
L = [0] * length
for i in xrange(length):
L[i] = randint(0, 9)
L[0] = randint(1, 9)
fout.write("".join(map(str, L)) + "\n") def MovData(srcFileName, desFileName):
with open(srcFileName, "r") as fin:
lines = fin.readlines()
with open(desFileName, "w") as fout:
fout.write("".join(lines)) def CompData():
print "comp"
srcFileName = "F:\Qt_prj\hdoj\data.out"
desFileName = "F:\workspace\cpp_hdoj\data.out"
srcLines = []
desLines = []
with open(srcFileName, "r") as fin:
srcLines = fin.readlines()
with open(desFileName, "r") as fin:
desLines = fin.readlines()
n = min(len(srcLines), len(desLines))-1
for i in xrange(n):
ans2 = int(desLines[i])
ans1 = int(srcLines[i])
if ans1 > ans2:
print "%d: wrong" % i if __name__ == "__main__":
srcFileName = "F:\Qt_prj\hdoj\data.in"
desFileName = "F:\workspace\cpp_hdoj\data.in"
GenData(srcFileName)
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. 【mongodb】 需求

    增删改查 增加:  (表名,增加内容) 删除: (表名,数据id) 改: (表名 根据id获取数据 修改 增加 查 (表名,字段 ) 关联查询? 请主站提供一下 在使用的接口

  2. POJ 3321 DFS序+线段树

    单点修改树中某个节点,查询子树的性质.DFS序 子树序列一定在父节点的DFS序列之内,所以可以用线段树维护. 1: /* 2: DFS序 +线段树 3: */ 4:   5: #include < ...

  3. Java 线程池框架核心代码分析

    前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和资源消耗都是很高的.线程池应运而生,成为我们管理线程的利器.Java 通过Executor接口,提供了一种标准的方法将任务的提交过 ...

  4. 微软职位内部推荐-Sr SDE for Win Apps Ecosystem

    微软近期Open的职位: Job posting title: Senior Software Design Engineer Location: China, Beijing Level: 63 D ...

  5. Android journey3 @点击事件的4种写法

    对于android布局中的控件,如Button等会有相应的点击事件去响应它所需要的功能,今天我们就以电话拨号器的代码说明下几种点击事件: package com.itheima.phone; impo ...

  6. 从状态转移看:载波侦听多路访问/冲突避免(CSMA/CA)

    CSMA/CA是写入IEEE802.11的无线网络MAC层标准协议,相信看到这篇文章的读者都知道它是用来做什么的.但许多短文对这个协议的解释都有所缺乏,因此本文用状态转换图的形式详细说明协议的工作流程 ...

  7. Azure VM 远程无法登陆问题(No Remote Desktop License)

    解决方法: 打开 Wins+R=> mstsc /v: yourVMIPadress /admin mstsc /v:xx.xx.xx.xx:54738 /admin

  8. setblendstate & setdepthstencilstate

    http://msdn.microsoft.com/en-us/library/windows/desktop/ff476462(v=vs.85).aspx blendstate blendfacto ...

  9. curPos和tgtPos

    curpos tgtpos 乍一看以为是当前位置和目标位置,但在项目里面这两个位置有点坑 当客户端玩家移动或者AI里面的位置,会把获得的位置付给tgtpos 而以前的tgtpos会付给curpos 所 ...

  10. js String Trim函数

    <javascript> String.prototype.trim = function() { return this.replace(/(^\s*)|(\s*$)/g,"& ...