博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[JZOJ 5894] [NOIP2018模拟10.5] 同余方程 解题报告(容斥)
阅读量:5082 次
发布时间:2019-06-13

本文共 2137 字,大约阅读时间需要 7 分钟。

题目链接:

题目:

题解:(部分内容来自0)

首先我们容斥一下,设calc(l,r)为i∈[1,l],j∈[q,r]的方程的解的个数,显然答案等于calc(r2,r1)-calc(l1-1,r2)-calc(r1,l2-1)+calc(l1-1,l2-1)

考虑如何计算calc(l,r)

对于l和r,从低位向高位枚举每一个二进制位1,强制把这个1改成0,这样可以保证得到的数小于原来的数并且没有算重。假设l改变第i位,r改变第j位

 (假设l不同的位比r后)

那么用红框表示已知部分,蓝框表示未知部分

所以异或之后就会变成这样

 

 中间的紫色部分表示一半已知,一半未知,后面的蓝色部分表示完全未知


显然未知部分可以取到任何可能

考虑中间的紫色部分,由于$a$紫色部分确定,$b$紫色部分不确定,那么对于每一个$b$的紫色部分都对应一个$c$的紫色部分

也就是说,每一个$b$确定$2^{蓝色部分长度}$个$c$,且我们一共有$2^{max(i,j)}-1$个$b$。由于未知部分可以取到任何可能,所以我们一共有$2^{max(i,j)}-1$个$c$

考虑到每个c肯定是平等的,那么每个c就被计算了$\frac{2^{蓝色部分长度} \times (2^{max(i,j)}-1)}{2^{max(i,j)}-1}=2^{蓝色部分长度}$次

$mx=max(i,j)$,发现c的取值就是[((S/p[mx])*mx)^p[mx],((S/p[mx])*mx)^p[mx]+p[mx]-1],p[mx]=1<<mx

注意到第mx位是需要和原来相反的,所以要^p[mx]

 


 还有三种情况

1.i==j

这个其实差不多,只是第mx位不需要取反,也就是不需要^p[mx]

2.a或b不改任何一位

这个也是一样的,注意一下变的那一个枚举的任何一位都需要取反

3.a和b都不变

这个直接异或一下直接判断就是了

#include
#include
#include
#include
using namespace std;typedef long long ll;const int N=60;const int mod=998244353;ll m;ll bin[N],p[N];int a[N],b[N];ll get(ll l,ll r){ if (l>r) return 0; if (l) return (r/m-(l-1)/m)%mod; else return (r/m+1)%mod;//要考虑0}ll calc(ll l,ll r){ int A=-1,B=-1; ll res=0,S=l^r; while (l) { a[++A]=l&1; l>>=1; } while (r) { b[++B]=r&1; r>>=1; } for (int i=0;i<=A;i++) if (a[i]) res=(res+get(((S/p[i])*p[i])^p[i],((S/p[i])*p[i])^p[i]+p[i]-1))%mod;//b不变 for (int i=0;i<=B;i++) if (b[i]) res=(res+get(((S/p[i])*p[i])^p[i],((S/p[i])*p[i])^p[i]+p[i]-1))%mod;//a不变 for (int i=0;i<=A;i++) if (a[i]) for (int j=0;j<=B;j++) if (b[j]) { int mx=max(i,j);//特判i==j if (i!=j) res=(res+get(((S/p[mx])*p[mx])^p[mx],((S/p[mx])*p[mx])^p[mx]+p[mx]-1)*bin[min(i,j)])%mod; else res=(res+get(((S/p[mx])*p[mx]),((S/p[mx])*p[mx])+p[mx]-1)*bin[min(i,j)])%mod; } return res+((S%m)==0);//i==l&&j==r}int main(){ freopen("mod.in","r",stdin); freopen("mod.out","w",stdout); p[0]=1;bin[0]=1; for (int i=1;i

 

转载于:https://www.cnblogs.com/xxzh/p/9795017.html

你可能感兴趣的文章
UVa540 Team Queue(队列queue)
查看>>
mysql数据增删改查
查看>>
shell中下载最新版本或指定版本的办法(Dockerfile 中通用)
查看>>
极客时间-左耳听风-程序员攻略-分布式架构工程设计
查看>>
akka之种子节点
查看>>
不知道做什么时
查看>>
matlab 给某一列乘上一个系数
查看>>
密码学笔记——培根密码
查看>>
Screening technology proved cost effective deal
查看>>
MAC 上升级python为最新版本
查看>>
创业老板不能犯的十种错误
查看>>
Animations介绍及实例
查看>>
判断请求是否为ajax请求
查看>>
【POJ2699】The Maximum Number of Strong Kings(网络流)
查看>>
spring boot配置跨域
查看>>
BZOJ 1996 合唱队(DP)
查看>>
进击吧!阶乘——大数乘法
查看>>
安卓学习资料推荐-25
查看>>
Mysql数据库备份和还原常用的命令
查看>>
关于退出当前页面在火狐的一些问题
查看>>