BZOJ 3329 Xorequ (数位DP、矩阵乘法)

手动博客搬家: 本文发表于20181105 23:18:54, 原地址https://blog.csdn.net/suncongbo/article/details/83758728

题目链接

https://www.lydsy.com/JudgeOnline/problem.php?id=3329

思路分析:

这道题完全是两道题拼在了一起。。
我们首先观察一下这个等式:
我们不妨可以把它移项变成\(x\ xor\ (2x)=3x\)
然后我们发现,\(3x=x+2x\), 也就是\(x\ xor\ (2x)=x+2x\).
并且显然有不等式\(|x-y|\le x\ and\ y\le x \ xor\ y\le x \ or\ y\le x+y\), 故有\(x\ or\ 2x=x+2x\), 也即\(x\ and\ 2x = 0\).
这意味着什么?我们考虑一个\(x\):

x    = 00110111001010111010100111011
2x   = 01101110010101110101001110110
x^2x = 01011001011111001111101001101

观察可得,\(x\ xor\ 2x\)相当于将二进制表示作了异或差分。同时,所有相邻的\(1\)只会保留最后一个和第一个的前一个,而中间这一部分都会被变成\(0\). 因此,题目中的等式成立等价于\(x\)的二进制表示下不存在相邻的\(1\).
另一种理解方式是:异或相当于二进制不进位加法,而既然是不进位加法,那么一旦进了位就会对数值有损失,当且仅当\(x+2x\)不进位的时候它才等于\(x\ xor\ 2x\). 而\(2x\)相当于把\(x\)的二进制表示左移一位,进位发生当且仅当\(x\)与\(2x\)在同一位置上都为\(1\),也即\(x\)有连续的至少两个\(1\).
完成了这一步转化之后,问题就相当于求\(n\)或者\(2^n\)内有多少数的二进制表示下不存在两个连续的\(1\).
第二问
\([0,2^n-1]\)之内的数对应长度为\(n\)的\(01\)序列,不能有连续两个\(1\), 这显然是斐波那契数列。(因为有一种进制叫斐波那契进制,有一个定理是任何一个整数都可以被唯一地划分成若干不连续的斐波那契数之和)严谨一些的证明是,设\(F(n)\)表示长度为\(n\)的满足条件的\(01\)序列有多少个,则\(F(n)\)如果第一位为\(1\), 那么第二位必然为\(0\), 后面\(n-2\)位方案数\(F(n-2)\); 如果第一位为\(0\), 那么后面的位任选,方案数\(F(n-1)\). 因此\(F(n)=F(n-1)+F(n-2)\).
但是我们刚才讨论的是\([0,2^n-1]\), 但题目要求的是\([1,2^n]\), 显然\(0\)必定满足条件,\(2^n\)也必定满足条件,因此答案为\(F(n)-1+1=F(n)\).
用矩快速幂递推即可,时间复杂度\(O(\log n)\), \(8\)倍常数。
第一问
这一问对\(n\)有更细致的要求,每一位都有要求,因此采取数位\(dp\).
设\(dp[i][j=0/1][k=0/1]\)表示有多少个\(i\)位数 (\([0,2^i-1]\))满足条件,且第\(i\)位是否必须选\(0\) (即如果\(j\)为\(1\)则必须选\(0\), 否则选\(0,1\)均可),\(k\)表示是否卡上界。考虑转移,这一位能够选\(1\)的条件是,\(j\)是\(false\), 并且选了\(1\)之后不会超过\(n\)的限制。超过\(n\)的限制的充要条件是,当前卡上界,且\(n\)这一位为\(0\). 这一位选\(0\)无条件转移。于是就可以成功DP了,时间复杂度\(O(\log n)\), 常数\(4\)倍。
(但是由于蒟蒻太傻,写代码的时候用了大量的(!(n&(1<<(pos-1))))来判断\(n\)这一位是否为\(0\), 因此代码十分丑陋,有的地方\(7\)层括号套起来。。希望读者见谅)

代码实现
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define llong long long
#define ldouble long double
#define uint unsigned int
#define ullong unsigned long long
#define udouble unsigned double
#define uldouble unsigned long double
#define modinc(x) {if(x>=P) x-=P;}
#define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define piiii pair<pair<int,int>,pair<int,int> >
#define pli pair<llong,int>
#define pll pair<llong,llong>
#define Memset(a,x) {memset(a,x,sizeof(a));}
using namespace std;llong n;namespace Subtask1
{const int N = 60;llong dp[N+2][2][2];llong dfs(int pos,bool f,bool t){
//  printf("DFS %d %d %d %lld\n",pos,(int)f,(int)t,dp[pos][f][t]);if(pos==1) return dp[pos][f][t] = 1ll+(f==false && (!(t&&(!(n&(1ll<<(pos-1)))))));if(dp[pos][f][t]) return dp[pos][f][t];llong cur = dfs(pos-1,false,(t&&(!(n&(1ll<<(pos-1))))));if(f==false && (!(t&&(!(n&(1ll<<(pos-1))))))) cur += dfs(pos-1,true,t);
//  printf("dfs %d %d %d %lld\n",pos,(int)f,(int)t,cur);return dp[pos][f][t] = cur;}void solve(){memset(dp,0,sizeof(dp));llong ans = dfs(N,false,true);printf("%lld\n",ans-1);}
}namespace Subtask2
{const int N = 3;const int P = 1e9+7;struct Matrix{llong a[N+2][N+2];int sz1,sz2;Matrix() {}Matrix(int _sz){sz1 = sz2 = _sz;for(int i=1; i<=sz1; i++){a[i][i] = 1ll;for(int j=1; j<=sz2; j++){if(i!=j) a[i][j] = 0ll;}}}void clear(){for(int i=1; i<=sz1; i++) for(int j=1; j<=sz2; j++) a[i][j] = 0ll;}void setsz(int _sz) {sz1 = sz2 = _sz; clear();}void setsz2(int _sz1,int _sz2) {sz1 = _sz1,sz2 = _sz2; clear();}};Matrix operator *(Matrix m1,Matrix m2){Matrix ret; ret.setsz2(m1.sz1,m2.sz2);for(int i=1; i<=m1.sz1; i++){for(int j=1; j<=m2.sz2; j++){ret.a[i][j] = 0ll;for(int k=1; k<=m1.sz2; k++){ret.a[i][j] += m1.a[i][k]*m2.a[k][j];}ret.a[i][j] %= P;}} return ret;}Matrix mquickpow(Matrix x,llong y){Matrix cur = x,ret = Matrix(x.sz1);for(int i=0; y; i++){if(y&(1ll<<i)) {ret = ret*cur; y-=(1ll<<i);}cur = cur*cur;} return ret;}void solve(){Matrix fib; fib.setsz(2); fib.a[1][1] = fib.a[1][2] = fib.a[2][1] = 1ll; fib.a[2][2] = 0ll;Matrix ori; ori.setsz2(1,2); ori.a[1][1] = ori.a[1][2] = 1ll;Matrix gg = ori*fib;Matrix fibn = ori*mquickpow(fib,n); llong ans = fibn.a[1][1];printf("%lld\n",ans);}
}int main()
{int T; scanf("%d",&T);while(T--){scanf("%lld",&n);Subtask1::solve();Subtask2::solve();}return 0;
}

发表于 2019-01-22 19:53 suncongbo 阅读(...) 评论(...) 编辑 收藏

刷新评论刷新页面返回顶部

BZOJ 3329 Xorequ (数位DP、矩阵乘法)相关推荐

  1. 【bzoj3329】Xorequ 数位dp+矩阵乘法

    题目描述 输入 第一行一个正整数,表示数据组数据 ,接下来T行 每行一个正整数N 输出 2*T行 第2*i-1行表示第i个数据中问题一的解, 第2*i行表示第i个数据中问题二的解, 样例输入 1 1 ...

  2. bzoj 3329: Xorequ(DP+矩阵快速幂)

    3329: Xorequ Time Limit: 1 Sec  Memory Limit: 256 MB Submit: 1134  Solved: 491 [Submit][Status][Disc ...

  3. BZOJ 3329: Xorequ(数位dp+递推)

    传送门 解题思路 可以把原式移项得\(x\)^\(2x\)=\(3x\),而\(x+2x=3x\),说明\(x\)二进制下不能有两个连续的\(1\).那么第一问就是一个简单的数位\(dp\),第二问考 ...

  4. 【BZOJ 3326】[Scoi2013]数数 数位dp+矩阵乘法优化

    挺好的数位dp-- 先说一下我个人的做法: 经过观察,发现这题按照以往的思路从后往前递增,不怎么好推,然后我就大胆猜想,从前往后推,发现很好推啊,维护四个变量,从开始位置到现在有了i个数 f[i]:所 ...

  5. bzoj 3329: Xorequ

    Description Solution 移项: \(X\) \(xor\) \(2X=3X\) 因为 \(X+2X=3X\), 所以 \(X\) 和 \(2X\) 相同位置不能同时为\(1\),也就 ...

  6. 51nod1836-战忽局的手段【期望dp,矩阵乘法】

    正题 题目连接:http://www.51nod.com/Challenge/Problem.html#problemId=1836 题目大意 nnn个点mmm次随机选择一个点标记(可以重复),求最后 ...

  7. P3193-[HNOI2008]GT考试【KMP,dp,矩阵乘法】

    正题 题目链接:https://www.luogu.com.cn/problem/P3193 题目大意 求有多少个长度为nnn的字符串不包含子串sss. 解题思路 考虑dpdpdp,用fi,jf_{i ...

  8. P5004-专心OI - 跳房子【dp,矩阵乘法】

    正题 题目链接:https://www.luogu.org/problemnew/show/P5004 题目大意 把NNN个无色格子排成一行,可以把某些格子染成黑色,但两个黑色格子之间必须至少有MMM ...

  9. [BZOJ]4180: 字符串计数 SAM+矩阵乘法+二分

    Description SD有一名神犇叫做Oxer,他觉得字符串的题目都太水了,于是便出了一道题来虐蒟蒻yts1999. 他给出了一个字符串T,字符串T中有且仅有4种字符 'A', 'B', 'C', ...

最新文章

  1. 毛永胜计算机教师,中国文化中心笛子教师与毛国立音乐学院师生交流
  2. 「鸡娃」是家长无处安放的「应试」焦虑
  3. AI安全初探——利用深度学习检测DNS隐蔽通道
  4. json 数据 生成 图表_CAPP工艺图表 / 知识重用 快速编制
  5. 了解mysqlpump工具
  6. freemind在ubuntu20.04下面的安装
  7. jboss fuse 教程_使用JBoss Fuse和OpenShift进行Cloud Native Camel骑行
  8. lora无线模块基于LoRaWAN网关技术在国家物联网应用
  9. ios怎么下载java游戏平台_如何快速下载并安装 iOS 模拟器
  10. STM32F103C8T6红外遥控解码
  11. 2017java考证_Sun认证Java程序员考试试题
  12. android提交sql语句,sql的提交 - 亭子happy的个人页面 - OSCHINA - 中文开源技术交流社区...
  13. java中BOM是什么_Java-BOM与DOM对象
  14. 广州华锐互动提供商场AR大屏互动制作一站式解决方案
  15. 【SSH】--鸿雁传书,信件发送
  16. 计算机毕业设计Java心理健康管理系统(源码+系统+mysql数据库+Lw文档)
  17. Wi-Fi Direct 和 wifi display
  18. 详谈软件架构设计(一)之软件架构的概念以及风格-上
  19. leetcode常用思路总结与文章索引
  20. ssm体育课堂管理系统毕业设计源码181626

热门文章

  1. 30分钟正则表达式指导
  2. C#中线程池的简单应用
  3. JavaScript事件绑定的方法说明 收藏
  4. 一文带你弄懂普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法
  5. 「 每日一练,快乐水题 」917. 仅仅反转字母
  6. 【快乐水题】1816. 截断句子
  7. STM32开发 -- HardFault_Handler处理
  8. stl-unique()函数去重
  9. java文件名特殊字符_Java 8:用名字读取特殊字符的文件
  10. Contextualizing Airbnb by Building Knowledge Graph