牛客提高R5 A.同余方程
题意
Sol
设\(solve(x, y)\)表示\(i \in [0, x], j \in [0, y]\)满足题目要求的方案数
首先容斥一下,\(ans = solve(r_1, r_2) - solve(l_1 - 1, r_2) - solve(l_2 - 1, r_1) + solve(l_1 -1, l_2 - 1)\)
然后按照套路按位拆分,这里拆的时候是直接对\(x, y\)进行拆分
这样就把问题转换成了看起来似乎简单一些的问题
假设拆完后的数是
110011101
1011
我们只要对于任意一对为1的位,求出小于该位的所有合法解即可
比如\(i = 3, j = 1\)我们要计算的就是\([110010000, 110010111]\)与\([1000, 1001]\)内的合法解
两种都可以写成\([v, v + 2^k]\)的性质
先考虑一种简单的情况,即\(v = 0\)
假设\(i > j\),那么\(\forall z = x \oplus y \leqslant 2^i\), 对于任意的\(x \leqslant 2^j\),都会有唯一的\(y\)与之对应
那么我们只要数出\([0, 2^i]\)中\(\% M == 0\)的数的个数,再乘上\(2^j\)即可
存在\(a[i]\)的限制实际上是一样的。
但是这样统计到的实际上是开区间的信息,只要在右端点处+1即可
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const LL mod = 998244353;
LL l1, r1, l2, r2, M;
LL add(LL x, LL y) {
return (x + y >= mod) ? (x + y - mod) : (x + y);
}
LL calc(LL l, LL r) {
if(l == 0) return ((r / M) + 1) % mod;
return (r / M - (l - 1) / M) % mod;
}
LL solve(LL X, LL Y) {
LL ans = 0;
for(LL i = 0, p1 = X; p1; i++, p1 >>= 1) {
for(LL j = 0, p2 = Y; p2; j++, p2 >>= 1) {
if((p1 & 1) && (p2 & 1)) {
LL x = i, y = j; if(x < y) swap(x, y);
LL ll = ((((p1 ^ 1) << i) ^ ((p2 ^ 1) << j)) >> x) << x;
ans = add(ans, (1ll << y) % mod * calc(ll, ll + (1ll << x) - 1) % mod);
//cout << ans << endl;
}
}
}
// cout << ans << endl;
return ans;
}
int main() {
cin >> l1 >> r1 >> l2 >> r2 >> M;
cout << (solve(r1 + 1, r2 + 1) - solve(l1, r2 + 1) + mod - solve(r1 + 1, l2) + mod + solve(l1, l2) + mod) % mod;
return 0;
}
/*
1 1 1 1 1
*/
牛客提高R5 A.同余方程的更多相关文章
- 【牛客提高训练营5A】同余方程
题目 吉老师的题做不动啊 首先\([l_1,r_1],[l_2,r_2]\)并不是非常好做,我们考虑将其拆成前缀信息 设\(solve(n,m)=\sum_{i=0}^n\sum_{j=0}^m[m| ...
- 牛客提高集训营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 ...
- 牛客提高D4t3 清新题
分析 树上从下往上线性基合并即可 并不需要启发式/xyx 代码 #include<iostream> #include<cstdio> #include<cstring& ...
- 牛客提高D4t2 卖羊驼
分析 不难想到dp[i][j]表示前i个数分了j组的最大值 我们发现这个dp状态有决策单调性 g[i][j]表示对于第i个数它的第j位最近出现的位置 每次一定从这些点转移 预处理即可 似乎还可以做到1 ...
- 牛客提高D4t1 麻将
分析 我们对于每一个点记录他所在的这一行以它为右端点向前最多有几个连续的1 之后我们考虑每一列 对每一列的点按照之前求出的值从小到大排序 一次考虑每一个宽度 而高度也可以很容易的求出 每次取最大值即可 ...
随机推荐
- Python获取网页Html文本
Python爬虫基础 1.获取网页文本 通过urllib2包,根据url获取网页的html文本内容并返回 #coding:utf-8 import requests, json, time, re, ...
- javascript,图片框
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- c语言和c++的相互调用
1.c与c++编译方式 (1)gcc和g++都可以编译.c文件,也都可以编译.cpp文件.g++和gcc是通过后缀名来辨别是c程序还是c++程序的(这一点与Linux辨别文件的方式不同,Linux是通 ...
- screen虚拟终端
screen命令相当于后台执行(虚拟终端) 用法:在一些要执行很久的操作,比如我有个文件有10个G,要传输一天左右,你如果是直接传输,万一你的连接断了.是不是意味着你的操作白费的呢,这时我们可以打开一 ...
- Takari Extensions for Apache Maven (TEAM)
http://takari.io/book/index.html TEAM stands for the Takari Extensions for Apache Maven. TEAM is a c ...
- Android 绑定Service并与之通信
1.绑定service 2.实现方法 3.在Androidmanifest.xml文件中配置service <service android:name=".Myservice" ...
- window 系统 cygwin swool 问题
cygwin 终端乱码 端口占用 查看 tcp 端口: netstat -tno 或者 netstat -an | grep 端口 杀死进程号 : kill 进程号 ---> 143 ...
- POJ_1456 Supermarket 【并查集/贪心】
一.题面 POJ1456 二.分析 1.贪心策略:先保证从利润最大的开始判断,然后开一个标记时间是否能访问的数组,时间尽量从最大的时间开始选择,这样能够保证后面时间小的还能够卖. 2.并查集:并查集直 ...
- Linux设备驱动开发基础--内核定时器
1. Linux内核定时器是内核用来控制在未来某个时间点(基于jiffies)调度执行某个函数的一种机制,其实现位于 <Linux/timer.h> 和 kernel/timer.c 文件 ...
- SQL异常捕获
直接上代码: GO BEGIN TRY DECLARE @res INT SET @res=1/0 PRINT 'no error' END TRY BEGIN CATCH PRINT 'Error ...