HDU3693 Math Teacher's Homework ---- 数位DP
HDU3693 Math Teacher's Homework
一句话题意
给定$n, k以及m_1, m_2, m_3, ..., m_n$求$x_1 \oplus x_2 \oplus x_3 \oplus ... \oplus x_n == K(x_1 \leq m_1, x_2 \leq m_2...)$ 的方案数。
题解
一开始口糊了一下,然后写代码的时候发现不少东西没考虑周到,于是就看起了题解。
我们首先需要发现一个重要的性质:
如果某一位上不受m限制(也就是选0或选1都可以)那么无论其它数的这一位位选什么都可以通过这一位来变成结果和K的这一位相等
为了避免来自$x <= m$的麻烦,我们首先让$m ++$, 使条件变为$x < m$。
然后按照数位dp的套路对位分析。
首先假设我们处理到了第j位,然后从高位到$j + 1$位都已经到了最大值
然后第$j$位由于要小于m,所以m的这一位必然1,然后j的这一位必然是0
然后按照套路我们发现如果这一位我们选了0,那么后面的位随便选都不会大于m
为了方便dp,我们令每一位最早允许随便选的那个$x_i$为$A_j$,这个数将在后面被限制以使其它自由位达到K上对应位的要求
我们记第j位上的第i个数字为自由的,当且仅当这个位不是被m限制了(即第i个数从高位枚举到第一个比m小的位置),且不是那些被最早选择(上一行的定义)限制的数字。
然后每一位上的方案数就是$2^{自由数个数-1}$
于是我们设$dp[i][j][0/1]$表示第i个数的“第i个数从高位枚举到第一个比m小的位置”为j,此位的异或值为0/1
下面我们记
$num[i][j]$为第i个数字第j位
$sum[i][j]$为j位上从第一个数字异或到第i个数字的结果
然后分情况(自由数位置)讨论从状态$dp[i - 1][k][r]$(注意大小写)(注意下面$2^x$的下标)转移,若
m此位可以有不同限制,即$num[i][j] == 1$
$j < k$:$dp[i][j][sum[i - 1][j]] += dp[i - 1][k][r] * 2^k$
$j > k$:$dp[i][k][r \oplus sum[i - 1][j]] += dp[i - 1][k][r] * 2^j$
$j == k$:$dp[i][j][r] += dp[i - 1][k][r] * 2^k$
最后要求$k[j] == sum[n][j]$的时候才能统计入答案
(然而我并不知道怎么用Latex打出'^' ......)
代码如下:
#include <cstdio> #include <bitset>
#include <cstring> using namespace std; char buf[], *pc = buf; inline void Main_Init(){
static bool inited = false;
if(inited) fclose(stdin), fclose(stdout);
else {
fread(buf, , , stdin);
inited = true;
}
} inline int read(){
int num = ;
char c;
while((c = *pc ++) < );
while(num = num * + c - , (c = *pc ++) >= );
return num;
} //Source Code const int MAXN = ;
const int MAXM = ;
const int MODS = ; int n, ans;
int x[MAXN];
unsigned int bin[MAXM];
int dp[MAXN][MAXM][]; bitset<> K, num[MAXN], sum[MAXN]; int main(){
Main_Init();
for(int i = ; i < ; i++) bin[i] = << i;
while(n = read(), n){
K = read();
for(int i = ; i <= n; i++)
num[i] = x[i] = read() + ;
memset(sum, , sizeof(sum)), memset(dp, , sizeof(dp));
ans = ;
dp[][][] = ;
for(int j = ; j < ; j++) sum[][j] = num[][j];
for(int i = ; i <= n; i++)
for(int j = ; j < ; j++)
sum[i][j] = sum[i - ][j] ^ num[i][j];
for(int i = ; i <= n; i++){
for(int j = ; j < ; j++){
if(!num[i][j]) continue;
for(int k = ; k < ; k++){
for(int r = ; r < ; r++){
if(dp[i - ][k][r]){
if(j > k) dp[i][j][sum[i - ][j]] = (dp[i][j][sum[i - ][j]] + 1ll * dp[i - ][k][r] * bin[k]) % MODS;
else if(j < k) dp[i][k][r ^ num[i][k]] = (dp[i][k][r ^ num[i][k]] + 1ll * dp[i - ][k][r] * bin[j]) % MODS;
else dp[i][j][r] = (dp[i][j][r] + 1ll * dp[i - ][k][r] * bin[k]) % MODS;
}
}
}
}
}
for(int i = ; i >= && K[i + ] == sum[n][i + ]; i--)
ans = (1ll * ans + dp[n][i][K[i]]) % MODS;
printf("%d\n", ans);
}
Main_Init();
return ;
}
HDU3693 Math Teacher's Homework ---- 数位DP的更多相关文章
- Math teacher's homework
Title:[Math teacher's homework] Description 题目大意:给你n个数m1,m2...mn,求满足X1 xor X2 xor ... xor Xn=k,0< ...
- POJ 3986 Math teacher's homework
题目 给出\(n,m_1,m_2,...,m_n\),求\(x_1 xor x_2 xor ... xor x_n=k (0 \leq x_i \leq m_i)\)的解的数量.二进制位数小于\(32 ...
- 题解 Math teacher's homework
题目传送门 题目大意 给出 \(n,k\) 以及 \(a_{1,2,...,n}\) ,求有多少个 \(m_{1,2,...,n}\) 满足 \(\forall i,m_i\le a_i\) 且 \( ...
- hiho1259 A Math Problem (数位dp)
题目链接:http://hihocoder.com/problemset/problem/1259 题目大意:g(t)=(f(i)%k=t)的f(i)的个数 求所有的(0-k-1)的g(i)的异或总值 ...
- 2018.09.28 hdu5435A serious math problem(数位dp)
传送门 数位dp卡常题. 写了一发dfs版本的发现过不了233. 于是赶紧转循环版本. 预处理出f数组. f[i][j]f[i][j]f[i][j]表示前i位数异或和为j的方案数. 然后每次直接数位d ...
- HDU 4507 (鬼畜级别的数位DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4507 题目大意:求指定范围内与7不沾边的所有数的平方和.结果要mod 10^9+7(鬼畜の元凶) 解题 ...
- HDU 2089 数位dp入门
开始学习数位dp...一道昨天看过代码思想的题今天打了近两个小时..最后还是看了别人的代码找bug...(丢丢) 传说院赛要取消 ? ... 这么菜不出去丢人也好吧~ #include<stdi ...
- hdu5787(数位dp)
基础的数位dp,才发现今天才终于彻底搞懂了数位dp... // // main.cpp // hdu5787.1 // // Created by New_Life on 16/8/10. // Co ...
- [kuangbin带你飞]专题十五 数位DP
ID Origin Title 62 / 175 Problem A CodeForces 55D Beautiful numbers 30 / 84 Problem B HD ...
随机推荐
- Kubernetes Pod详解
目录 基本概念 pod资源配额 容器的健康检查 静态pod 基本概念 Pod是kubernetes集群中最基本的资源对象.每个pod由一个或多个业务容器和一个根容器(Pause容器)组成.Kubern ...
- Linux 磁盘自动挂载
磁盘代号或者装置的Label 挂载点 档案系统格式 档案系统参数 是否用dump备份 是否用fsck检查扇区 0 0 1 1 2 2 下面来写一个代表的 ...
- Linux命令(八)Linux系统信息相关命令
top:
- Spring RedisTemplate操作-Set操作(5)
@Autowired @Resource(name="redisTemplate") private RedisTemplate<String, String> rt; ...
- 面板支持单个,多个元素的jQuery图片轮播插件
一.先附上demo <!doctype html> <html> <head> <meta charset="utf-8"> < ...
- jQuery下ajax事件的简单分析
昨天写了一篇关于监视页面动态生成元素问题的文章,引起了一些小小的争议,不过我从中学到了很多.文章在这,<jQuery下实现等待指定元素加载完毕>当然 动态生成的节点元素 分很多种情况,这里 ...
- 20155230 2016-2017-2 《Java程序设计》第五周学习总结
20155230 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 1.错误处理通常称为异常处理. 2.catch括号中列出的异常不得有继承关系,否则会发生编译 ...
- if语句引起的bug
最近维护高手留下的api项目,客户端反馈一个bug过来,然后查找到可能出错的代码位置,是一个if语句,乍一看好像没什么问题,代码如下: if (company.UserId != userId || ...
- 在线建立或重做mysql主从复制架构方法(传统模式和GTID模式)【转】
mysql主从复制架构,是mysql数据库主要特色之一,绝大多数公司都有用到. 而GTID模式是基于事务的复制模式的意思,发展到现在也是越来越多人用. 以前很多文章,介绍搭建mysql主从复制架构,是 ...
- testng运行失败,继续执行
1.重写断言类 public class Verify { public static StringBuffer verificationErrors= new StringBuffer();; pu ...