Math teacher's homework
Title:【Math teacher's homework】#
Description##
题目大意:给你n个数m1,m2...mn,求满足X1 xor X2 xor ... xor Xn=k,0<=Xi<=mi (1<=i<=m)的方案数
Input Format##
多组数据(至多100组)每组数据第一行包括两个整数n,k,第二行包括n个整数m1,m2...mn(1<=n<=50,0<=k,mi<=\(2^{31}-1\)(1<=i<=n))
输入以0 0结尾
Output Format##
对于每组数据输出一行表示题目中描述的方案数,方案数可能很大,你只需输出方案数mod 1000000003的结果
Sample Input##
11 2047
1024 512 256 128 64 32 16 8 4 2 1
10 2047
1024 512 256 128 64 32 16 8 4 2
0 0
Sample Output##
1
0
Solution##
还是太菜了,这道题看了很很很很很久
废话不说了
首先,我们把mi+1,那么我们Xi的限制条件自然改变了,变成了1<=Xi<mi(1<=i<=n)
然后我们来分析一下如何进行数位DP
对于Xi,从高位开始比较,必然有若干个高位与mi相等,我们把相等的这些位涂成深蓝色,第一个与mi不同的位涂成绿色(由于Xi一定小于mi,mi的该位必然为1,Xi的该位必然为0)
如果该题没有限制,那么每一位异或为1或0的方案数应该都为\(2^{n-1}\),因为只要n-1个数随便取,用最后一个数改变异或值即可
也就是说,如果Xi已经确定了一位涂上了绿色,那么我们后面的格子就和没有限制是一样的了,那么我们只要固定每列的一个格子,其他格子便可以随便取了
由此我们规定每列最早出现的格子涂成橙色,其余格子涂成浅蓝色,那么,每一列的方案数就是\(2^{浅蓝色格子数-1}\)

有了这些基础我们就可以设计状态了,f[i][j][l]表示处理到第i个数最左边的绿色格子在第j位第j列的异或值为l的方案数
枚举对于f[i][j][0/1]我们枚举上一行的状态f[i-1][k][l],由上一行的状态来推出该行状态
我们用num[i][j]来存储mi的第j位数字(二进制下),用col[i][j]来记录第j位的数值从第一个数异或到mi的异或值,用b[i]表示\(2^i\)的值
接下来,分类讨论~~~
(1)当j>k时 f[i][j][col[i-1][j]]+=f[i-1][k][l]*b[k-1],由于第j格在该行为绿色格子,即其值为0,后面的蓝色格子可以任意取,因此该方程很容易理解
(2)当j=k时 f[i][j][l]+=f[i-1][k][l]*b[j-1],由于第j格在该行为绿色格子,即其值为0,且j,k位于同一列,后面的蓝色格子可以任意取,因此该方程很容易理解
(3)当j<k时 f[i][k][l^num[i][k]]+=f[i-1][k][l]*b[j-1],由于第j格在该行为绿色格子,即其值为0,后面的蓝色格子可以任意取,因此该方程很容易理解
但是由于绿色格子只存在于原数该位值为1的位上,所以方程符合题意当且仅当num[i][j]=1
还有一件事,就是如果最左边的绿色格子如果在第j位,则比j高位的col[n]k都必须与mi的第k位相等
emmmmm,讲到这里,只要记得mod 1000000003应该就没问题了吧(细节错了不要怪我瞎讲)
附代码咯
#include<cstdio>
#define mo 1000000003
#include<cstring>
#define me(a) memset(a,0,sizeof a)
int k,num[55][33],n,m,b[32],col[55][33],f[55][33][2],ans,md[33];
void in(int i){scanf("%d",&k);k++;int t=0;for(;k;)num[i][++t]=k&1,k>>=1;}
int main(){
b[0]=1;
for (int i=1;i<=31;i++) b[i]=b[i-1]*2;
while (~scanf("%d%d",&n,&m)){
if (!n&&!m) return 0;me(col),me(f),me(num),ans=0;f[0][1][0]=1;
for(int i=1;i<=n;i++)in(i);
for(int i=1;i<=n;i++)for(int j=1;j<=32;j++)col[i][j]=col[i-1][j]^num[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=32;j++)if(num[i][j])
for(int k=1;k<=32;k++)
for(int l=0;l<=1;l++)if(f[i-1][k][l]){
if(j>k)f[i][j][col[i-1][j]]=(f[i-1][k][l]*1ll*b[k-1]+f[i][j][col[i-1][j]])%mo;
else if(j==k) f[i][j][l]=(f[i-1][k][l]*1ll*b[k-1]+f[i][j][l])%mo;
else f[i][k][l^num[i][k]]=(f[i-1][k][l]*1ll*b[j-1]+f[i][k][l^num[i][k]])%mo;
}
for(int i=1;i<=32;i++)md[i]=m&1,m>>=1;
for(int i=32;md[i+1]==col[n][i+1]&&i;i--)ans=(1ll*ans+f[n][i][md[i]])%mo;
printf("%d\n",ans);
}
}
Math teacher's homework的更多相关文章
- 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 \ ...
- 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\) 且 \( ...
- HDU 5068 Harry And Math Teacher
主题链接~~> 做题情绪:的非常高深,有种高大上的感觉. 解题思路: 两层之间的联通能够看成是一个矩阵 代表上下两层都能够联通,,代表下层第1个门与上层第一个门不联通,以此类推联通就能够用矩阵 ...
- HDU 5068 Harry And Math Teacher 线段树+矩阵乘法
题意: 一栋楼有n层,每一层有2个门,每层的两个门和下一层之间的两个门之间各有一条路(共4条). 有两种操作: 0 x y : 输出第x层到第y层的路径数量. 1 x y z : 改变第x层 的 y门 ...
- 【转载】ACM总结——dp专辑
感谢博主—— http://blog.csdn.net/cc_again?viewmode=list ---------- Accagain 2014年5月15日 动态规划一 ...
- 【DP专辑】ACM动态规划总结
转载请注明出处,谢谢. http://blog.csdn.net/cc_again?viewmode=list ---------- Accagain 2014年5月15日 ...
- dp专题训练
****************************************************************************************** 动态规划 专题训练 ...
- 【DP专辑】ACM动态规划总结(转)
http://blog.csdn.net/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强, ...
随机推荐
- Add Two Numbers(链表)
You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...
- 记一次springMVC的跨域解决方案
日期:2019年5月18日 事情原因:由于微信小程序的开发只有测试环境,而后台提供借口的环境是开发环境:两个环境的域名不同,导致前端开发产生了跨域问题: 理论概念: 1.同源策略:同源策略是浏览器的安 ...
- Linux系统备份还原工具2(TAR/压缩工具)
相比DD备份还原工具,TAR压缩还原工具更加小巧和灵活,但是不能备份MBR.当然可以通过重新安装GRUB来解决MBR的这一问题.同时,TAR的做法也是官方推荐的. 注意:一个硬盘启动时最新经过MBR( ...
- Android GIS开发系列-- 入门季(7) 利用GeometryEngine坐标转换、计算距离与面积等
GeometryEngine是Arcgis的重要工具类,利用此工具类,可以计算地图上的距离.面积,将点.线.面转化为Json数据,将Json转化为点线面,坐标转换作用非常强大. 一.坐标转化 将用到方 ...
- VMware实用技巧
1.VM快照管理 这个功能实在太常用,不用我多废话.这里只是提醒一下还没有用过快照的同学,赶紧的给自己的VM保存点快照吧,这样VM里的系统出了问题或是有其它需要很容易让你还原到原来的某个点,这功能可比 ...
- Codeforces Round #306 (Div. 2) A B C
题目链接:http://codeforces.com/contest/550 A 暴力一发. 代码: #include <iostream> #include <stdio.h> ...
- Django打造大型企业官网(五)
4.6.切换轮播图的箭头样式以及显示和隐藏 templates/news/index.html <span class="arrow left-arrow">‹< ...
- php把时间计算成几分钟前,几小时前,几天前的函数
function time_tran($the_time){ $now_time = date("Y-m-d H:i:s",time()+8*60*60); $now_time = ...
- 10.11无法打开Xcode6.4的解决方法
前言 mac升级到10.11版本号并安装Xcode7.0Beta之后,Dock中的Xcode6.3图标上出现一个禁止符号,打开提示到App store更新最新版本号,更新到6.4之后问题依然,还是提示 ...
- mysql数据库批量高速插入
近期在处理一批数据,须要从库中表里的字段进行处理然后导出到一个新表中.只是这个表的数据量有近500w条. 这数据量出现的的问题是须要处理的时间好长. 首先想到,一句一句的插入,大数据量处理时间好长,忽 ...