【牛客提高训练营5A】同余方程
吉老师的题做不动啊
首先\([l_1,r_1],[l_2,r_2]\)并不是非常好做,我们考虑将其拆成前缀信息
设\(solve(n,m)=\sum_{i=0}^n\sum_{j=0}^m[m|(i\bigoplus j)]\)
于是我们的答案就变成了\(solve(r_1,r_2)-solve(l_1-1,r_2)-solve(r_1,l_2-1)+solve(l_1-1,l_2-1)\)
考虑\(solve(r_1,r_2)\)怎么求
一个非常特殊的情况是\(r_1=2^n-1,r_2=2^m-1\),不妨假设\(n<m\),则\([0,2^n)\)和\([0,2^m)\)各选择一个数异或起来,能取遍\([0,2^m)\),且每一个数出现的次数都是\(2^n\)
正确性显然
考虑推广到更一般的情况,我们把\([0,r_1)\)拆分一下,拆分成\(\log\)段\([v,v+2^k)\)的区间,比如说对于\(101010\),可以拆成\([0,2^5),[2^5,2^5+2^3),[2^5+2^3,2^5+2^3+2^1)\)
这样的拆分有一个特点,如果有\(v\neq 0\),那么一定会存在\(v>2^k\),这个性质接下来非常重要
将\([0,r_1),[0,r_2)\)各拆成\(\log\)段区间后,我们暴力从两边各选一段区间出来,假设为\([x,x+2^a)\)和\([y,y+2^b)\),还是不妨假设\(a<b\)
于是在忽略\(x,y\)的情况下两个区间变成了\([0,2^a),[0,2^b)\),于是各选一个异或起来能取遍\([0,2^b)\)且每个值能被异或出来\(2^a\)次
现在考虑把\(x,y\)引入,不难发现因为\(x>2^a\),所以从\([0,2^a)\)拿出一个数,加上\(x\)和异或\(x\)是等价的;\(y\)那边同理
于是\([0,2^b)\)中的每一个数拿出来和\(x\bigoplus y\)异或一下,就是真实的从\([x,x+2^a)\)和\([y,y+2^b)\)各拿一个数出来异或的结果。
所以现在只需要求出\([0,2^b)\)内有多少个满足异或\(x\bigoplus y\)后\(\rm mod\ m=0\),这样的数的个数乘上\(2^a\)就是答案了。
做到这里就不会了,接下来都是祖特教我的。
我们不难发现\(x\bigoplus y\)如果不是\(0\),则必然大于\(2^b\),于是\(x\bigoplus y\)和\([0,2^b)\)内的数异或,必然不会改变必\(2^b\)更高的二进制位。
所以想要使得异或出来的数是\(m\)的倍数,只需要让\(x\bigoplus y\)小于\(2^b\)的位数从全\(0\)取到全\(1\),从中选出\(m\)的倍数即可。
代码
#include<bits/stdc++.h>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int mod=998244353;
inline int dqm(int x) {return x<0?x+mod:x;}
inline int qm(int x) {return x>=mod?x-mod:x;}
LL l1,l2,r1,r2;int m,top[2];
struct Seg{LL v,k;}a[2][65];
inline LL getid(LL a,LL b) {return a%b==0?a/b:a/b+1;}
inline LL solve(LL n,LL k)
{
LL t=0,tot=0;
for(re LL i=63;i>=0;i--)
{
t|=(1ll<<i);
if(!(n&(1LL<<i))) continue;
LL l=k&t,r=l+(1ll<<i)-1;
LL L=getid(l,m),R=r/m;
tot=qm(tot+(R-L+1)%mod);
}
return tot;
}
inline int calc(LL n,LL m) {
++n,++m;int ans=0;
top[0]=top[1]=0;
LL now=0;
for(re LL i=63;i>=0;--i)
if(n>>i&1ll) {
a[0][++top[0]].v=now,a[0][top[0]].k=i;
now|=(1ll<<i);
}
now=0;
for(re LL i=63;i>=0;--i)
if(m>>i&1ll) {
a[1][++top[1]].v=now,a[1][top[1]].k=i;
now|=(1ll<<i);
}
for(re int i=1;i<=top[0];++i)
for(re int j=1;j<=top[1];++j) {
now=a[0][i].v^a[1][j].v;
LL mx=max(a[0][i].k,a[1][j].k),mn=min(a[0][i].k,a[1][j].k);
mn=(1ll<<mn);mn%=mod;
ans=qm(ans+1ll*solve(1ll<<mx,now)%mod*mn%mod);
}
return ans;
}
int main() {
scanf("%lld%lld%lld%lld%d",&l1,&r1,&l2,&r2,&m);
printf("%d\n",dqm(qm(calc(r1,r2)+calc(l1-1,l2-1))-qm(calc(l1-1,r2)+calc(r1,l2-1))));
return 0;
}
【牛客提高训练营5A】同余方程的更多相关文章
- 牛客提高R5 A.同余方程
题意 题目链接 Sol 设\(solve(x, y)\)表示\(i \in [0, x], j \in [0, y]\)满足题目要求的方案数 首先容斥一下,\(ans = solve(r_1, r_2 ...
- 【牛客提高训练营2B】分糖果
题目 发现自己一年之前非常垃圾 题目大意是给你一个\(n\)个点的环,给每个点一个\([1,a_i]\)的取值,并且满足环上任意相连两点权值不能相等,求方案数 考虑断环为链,发现不大会 不妨考虑所有\ ...
- 【牛客提高训练营5B】旅游
题目 吉老师的题时过一年还是不会做 从\(1\)号点出发经过每条边至少一次并且还要回到\(1\)号点,这跟欧拉回路的条件非常像,但是欧拉回路的实际上是"经过每一条边恰好一次并且回到出发点&q ...
- 牛客寒假训练营3 B 处女座的比赛资格(拓扑排序+最短路)
题目链接 这个题,一眼看上去就是最短路的题,边权有负环显然不能用dij,然后出题人又卡了spfa,,那怎么办的想点办法啊,好像还有一个拓扑排序可以求最短路吧,这时候正解就已经得到了,就是拓扑排序求最短 ...
- 牛客提高集训营6 C 树(树链剖分)
题目链接 为了纪(zhuang)念(bi)写完这个树剖单独写一篇.感觉还好,也就6k嘛. 完整比赛题解:https://www.cnblogs.com/SovietPower/p/9826829.ht ...
- 牛客提高D6t3 分班问题
分析 就就就是推柿子 看官方题解吧/px 代码 #include<iostream> #include<cstdio> #include<cstring> #inc ...
- 牛客提高D6t2 破碎的序列
分析 我们不难发现对于偶数的情况只要相邻两个数不相等即可 而对于奇数的情况只要中间恰好隔一个数的两个数不相等即可 于是我们又dp[i][0/1]表示考虑到第i位,这一位和它后面离它最近的一个确定的数是 ...
- 牛客提高D6t1 积木大赛
分析 每次修改用二位差分记录一下 之后对于三维分别统计即可 代码 #include<iostream> #include<cstdio> #include<cstring ...
- 牛客提高D5t1 deco的abs
分析 傻子题? 对d取模后随便贪心即可 代码 #include<iostream> #include<cstdio> #include<cstring> #incl ...
随机推荐
- yum安装apache
一.查询是否已经安装apache rpm -qa httpd 注:Apache在linux系统里的名字是httpd 如果有返回的信息,则会显示已经安装的软件.如果没有则不会显示其它的信息.如下图是 ...
- 我的scoi2018
高一,很尴尬,凉~ -------- 大家好,我是分界线,我弱弱的说本次采用倒序的写作手法 -------- 故事是这样讲的: Day0: 刚刚去那个电科搞的集训,早上才考了一波模拟赛,下午就过来住酒 ...
- c# DataTable第二行改为各列标题字段
DataTable dt = ExcelHelper.ToDataTable(fileinfo.FilePath); //将datatable的第二行变为列标题字段 DataTable dt2 = n ...
- shell同时输出多行信息
- JS window对象 Navigator对象 Navigator 对象包含有关浏览器的信息,通常用于检测浏览器与操作系统的版本。
Navigator对象 Navigator 对象包含有关浏览器的信息,通常用于检测浏览器与操作系统的版本. 对象属性: 查看浏览器的名称和版本,代码如下: <script type=" ...
- koa 中间件 koa-art-template 的使用
例子 const Koa = require('koa'); const render =require('koa-art-template'); const path= require('path' ...
- loj2472[九省联考2018]IIIDX
题意:要求构造一个d的排列使得满足d[i/k]<=d[u]且字典序最大. 标程(bzoj上并不能过): #include<bits/stdc++.h> #define mid ((l ...
- loj2573[TJOI2018]数字计算
题意:操作1:x=x*m,输出x%mod.2.x/=map[m].m即第m次操作,保证该次操作为1操作,并且每个操作最多只会被删一次.q<=1e5. 线段树维护操作信息的乘积,删除把对应位置的权 ...
- springMVC配置文件 的约束
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...
- 文件系统类型(ext4、ntfs)
Linux 1.Linux:存在几十个文件系统类型:ext2,ext3,ext4,xfs,brtfs,zfs(man 5 fs可以取得全部文件系统的介绍) 不同文件系统采用不同的方法来管理磁盘空间,各 ...