先前綴和一發,問題表示求[0-l2][0-r2]滿足條件的數的個數

假設可以把某一個數拆分成[前面任意個數][00…0-11…1(個數相同)]的區間

那麼問題會簡單的多,因為任意一個a位的整數分別xor[00…0(a個)-11…1(a個)]的結果會取遍00…0-11…1中的任意一個整數

這說明,我們拆出的區間大小都是2的冪次

很顯然想到x&-x操作,這個操作可以把某一個數最後的1去掉,從而新數和舊數形成的區間的大小是2的冪次

但是,x&-x操作是適用于區間開頭為1的情況,所以我們可以將要求的數加上1,記為b

這樣,b-1和b-b&-b就變成了一個合法的結尾為00…0-11…1的區間

我們可以枚舉每一個這樣子的區間,記00…0-11…1的長度,第一個區間為a,第二個為b

那麼異或起來的結果就是[兩個區間在max(a,b)之前的長度異或起來][max(a,b)個00…0-11…1]

這樣,問題就變成了求出連續區間中能被m整除的數的個數

實現上,我們可以枚舉a+1和b+1的每一個1位,則a+1在這一位後面和b+1在這一位後面的數全為00…0-11…1

然後我們可以把a和b的這一位去掉取前面的所有位,這樣可以計算出前面的部分

注意別忘記求出來的結果乘以另一個較短的位的00…0-11…1的數的個數

代碼:

#include<bits/stdc++.h>
using namespace std;
#define mo 998244353ll
typedef long long ll;
ll m;
ll get(ll l,ll r){
	if(l%m==0)return (r/m-l/m+1ll+mo)%mo;
	return (r/m-l/m+mo)%mo;
}
ll ct(ll a,ll b){
	ll ans=0;
	for(ll i=61;i>=0;i--)
		for(ll j=61;j>=0;j--)
			if((a&(1ll<<i))&&(b&(1ll<<j))){
				ll m1=max(i,j),m2=min(i,j);
				ll pre=((a^(1ll<<i))^(b^(1ll<<j)))&(~((1ll<<m1)-1ll));
				ll suf=pre+(1ll<<m1)-1ll;
				ans=(ans+get(pre,suf)*((1ll<<m2)%mo)%mo)%mo;
			}
	return ans;
}
int main(){
	freopen("mod.in","r",stdin);
	freopen("mod.out","w",stdout);
	ll a,b,c,d;
	scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&m);
	printf("%lld",(ct(b+1,d+1)-ct(b+1,c)-ct(a,d+1)+ct(a,c)+mo)%mo);
}

jzoj5894的更多相关文章

  1. JZOJ5894【NOIP2018模拟10.5】同余方程

    题目 Description

随机推荐

  1. svn回退版本/取消修改

    取消对代码的修改分为两种情况:   第一种情况:改动没有被提交(commit). 这种情况下,使用svn revert就能取消之前的修改. svn revert用法如下: # svn revert [ ...

  2. socket domain 样例

    服务端 #include<stdio.h> #include <sys/stat.h> #include <sys/socket.h> #include <s ...

  3. 讲讲我在Windows10(uwp)开发中遇到的一些坑.

    7月29日发布的Windows10正式版,当天安装好以后,在网络不太好的情况下,经过多次尝试终于装上了Visual Studio 2015和Windows 10 10240的SDK.这两周一直在开发U ...

  4. Windows10(uwp)开发中的侧滑

    还是在持续的开发一款Windows10的应用中,除了上篇博客讲讲我在Windows10(uwp)开发中遇到的一些坑,其实还有很多不完善的地方,比如(UIElement.Foreground).(Gra ...

  5. hdu-1107(模拟题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1107 注意:1.路线是要反向的,走不通就反向: 2.输入输出全部是整形 3.攻击力不断变化 #incl ...

  6. Vim配置(转)

    1.按F5可以直接编译并执行C.C++.java代码以及执行shell脚本,按“F8”可进行C.C++代码的调试 2.自动插入文件头 ,新建C.C++源文件时自动插入表头:包括文件名.作者.联系方式. ...

  7. 在centos7.1上安装systemd

    1.检查本地systemd的版本 [admin@localhost ~]$ systemctl --version          systemd 208   +PAM +LIBWRAP +AUDI ...

  8. Git客户端命令总结

    一:常用命令 1.先进入项目目录,然后git init:则会为此 项目/目录 创建一个本地仓库(或重新初始化这个本地仓库),可以用ls -a ./看到多了.git目录: 或者git init /hom ...

  9. trcd_extract_EDCD_new

    # -*- coding:utf-8 -*- import re ''' 适应新版本 ''' year='17A'#用户自定义 ss='./data/'#根目录 filename = ss+'EDCD ...

  10. MATLAB实现最优低通滤波器的函数

    MATLAB实现最优低通滤波器的函数 % Fs     --Data rate % Fpass  --pass band % Fstop  --Cutoff frequencies % Apass  ...