CodeForces 1327F AND Segments
题意
给三个整数 \(n,k,m\) 和 \(m\) 个限制 \((l_i,r_i,x_i)\),求有多少个长度为 \(n\) 的序列 \(a\) 满足:
对于 \(1\leq i\leq n\) 有 \(0\leq a_i<2^k\)
对于 \(1\leq i\leq m\) 有 \(a_{l_i} \operatorname{and} a_{l_i+1}\operatorname{and}\cdots\operatorname{and} a_{r_i}=x_i\)
对 \(998244353\) 取模。
\(\texttt{Data Range:}1\leq n\leq 5\times 10^5,1\leq k\leq 30,0\leq m\leq 5\times 10^5\)
题解
毒瘤题。
一个非常显然的想法是拆位,所以变成每个位置填 \(0\) 或 \(1\) 然后满足所有条件的限制的方案数,总的方案数就是每一位的方案数乘起来就好了。
如果一段区间限制为 \(1\) 的话那么所有数都必须填 \(1\),如果限制是 \(0\) 的话那么至少有一个是 \(0\)。
设 \(f_{i,j}\) 表示当前在位置 \(i\),最后一个 \(0\) 在位置 \(j\) 的方案数,然后你会发现这个东西不好做。
考虑设一个 \(p_i\) 表示 \(i\) 位置前(不包括 \(i\) 位置)第一个 \(0\) 最小能填到哪个位置。
当 \(j<p_i\) 的时候很明显 \(f_{i,j}=0\)。
当 \(p_i\leq j<i\) 的时候,因为 \(i\) 位置没有填,所以 \(f_{i,j}=f_{i-1,j}\)。
当 \(j=i\) 的时候,如果这个位置强制选 \(1\) 的话那么 \(f_{i,j}=0\),否则枚举一下上一个 \(0\) 的位置得到 \(f_{i,j}=\sum\limits_{k<j}f_{i-1,k}\)。
注意到 \(i\) 这一维可以滚掉,而 \(p_i\) 又是单调不降的,所以可以考虑用一个指针来维护一下满足 \(f_{i,j}\neq 0\) 的最小的 \(j\)。
至于第三种操作,因为当 \(i<j\) 的时候 \(f_{i,j}=0\),所以可以直接维护当前 \(i\) 的所有 \(f_{i,j}\) 的和即可。
然后处理出哪个位置要强制选 \(1\) 的话可以对 \(1\) 的限制涉及到的区间做区间加,可以差分一下再前缀和一下。
处理 \(p_i\) 可以考虑每个为 \(0\) 的限制 \((l,r,0)\),记 \(p_{r+1}=l\) 即可。
代码
#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=5e5+51,MOD=998244353;
ll n,kk,m,res=1,sum,ptr;
ll l[MAXN],r[MAXN],x[MAXN],pos[MAXN],sel[MAXN],f[MAXN];
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
inline void calc(ll bit)
{
for(register int i=1;i<=m;i++)
{
if(x[i]&(1<<bit))
{
sel[l[i]]++,sel[r[i]+1]--;
}
else
{
pos[r[i]+1]=max(pos[r[i]+1],l[i]);
}
}
f[0]=sum=1,ptr=0;
for(register int i=2;i<=n+1;i++)
{
sel[i]+=sel[i-1],pos[i]=max(pos[i],pos[i-1]);
}
for(register int i=1;i<=n+1;i++)
{
for(;ptr<pos[i];sum=(sum-f[ptr]+MOD)%MOD,f[ptr++]=0);
f[i]=sel[i]?0:sum,sum=(sum+f[i])%MOD;
}
res=(li)res*f[n+1]%MOD;
for(register int i=0;i<=n+1;i++)
{
sel[i]=pos[i]=f[i]=0;
}
}
int main()
{
n=read(),kk=read(),m=read();
for(register int i=1;i<=m;i++)
{
l[i]=read(),r[i]=read(),x[i]=read();
}
for(register int i=0;i<kk;i++)
{
calc(i);
}
printf("%d\n",res);
}
CodeForces 1327F AND Segments的更多相关文章
- codeforces 895B XK Segments 二分 思维
codeforces 895B XK Segments 题目大意: 寻找符合要求的\((i,j)\)对,有:\[a_i \le a_j \] 同时存在\(k\),且\(k\)能够被\(x\)整除,\( ...
- Codeforces 901C Bipartite Segments
Bipartite Segments 因为图中只存在奇数长度的环, 所以它是个只有奇数环的仙人掌, 每条边只属于一个环. 那么我们能把所有环给扣出来, 所以我们询问的区间不能包含每个环里的最大值和最小 ...
- Codeforces 901C Bipartite Segments(Tarjan + 二分)
题目链接 Bipartite Segments 题意 给出一个无偶环的图,现在有$q$个询问.求区间$[L, R]$中有多少个子区间$[l, r]$ 满足$L <= l <= r &l ...
- [离散化+树状数组]CodeForces - 652D Nested Segments
Nested Segments time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- Codeforces 976C Nested Segments
题面: 传送门 C. Nested Segments Input file: standard input Output file: standard output Time limit: 2 secon ...
- Codeforces 193D - Two Segments(线段树)
Codeforces 题目传送门 & 洛谷题目传送门 感觉这个 *2900 并不难啊,为什么我没想出来呢 awa 顺便膜拜 ycx 一眼秒掉此题 %%% 首先碰到这类题有两种思路,一是枚举两个 ...
- codeforces 652D Nested Segments 离散化+树状数组
题意:给你若干个区间,询问每个区间包含几个其它区间 分析:区间范围比较大,然后离散化,按右端点排序,每次更新树状数组中的区间左端点,查询区间和 注:(都是套路) #include<cstdio& ...
- Codeforces 193D Two Segments 解题报告
先是在蓝桥杯的网站上看到一道题: 给出1~n的一个排列,求出区间内所有数是连续自然数的区间的个数.n<=50000. 由于数据较弱,即使用O(N^2)的算法也能拿到满分. 于是在CF上发现了这一 ...
- codeforces 652D . Nested Segments 线段树
题目链接 我们将线段按照右端点从小到大排序, 如果相同, 那么按照左端点从大到小排序. 然后对每一个l, 查询之前有多少个l比他大, 答案就是多少.因为之前的r都是比自己的r小的, 如果l还比自己大的 ...
随机推荐
- How to write Chinese in LaTeX
Add the following package to the preamble. \usepackage{xeCJK} Write Chinese in your latex editor. Co ...
- Python练习题 003:完全平方数
[Python练习题 003]一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少? --------------------------------------- ...
- 单例模式,reorder详解,线程安全,双检查锁
单例模式,分为饿汉式单例 和 懒汉式单例. 先把本类对象所需内存在main函数执行前就new出来,这是饿汉式单例. 个人思考: 为什么饿汉式不独霸天下,还有什么必要去研究使用cpp11上支持的双检查锁 ...
- 初识 Istio - 服务网格管理工具
What is a service mesh(服务网格)? 微服务在国内流行已经多年了,大多数公司选择了基于容器化技术( Docker )以及容器编排管理平台 ( Kubernetes )落地微服务 ...
- OpenCV中threshold函数的使用
转自:https://blog.csdn.net/u012566751/article/details/77046445 一篇很好的介绍threshold文章: 图像的二值化就是将图像上的像素点的灰度 ...
- C++读写ini配置文件GetPrivateProfileString()&WritePrivateProfileString()
转载: 1.https://blog.csdn.net/fengbingchun/article/details/6075716 2. 转自:http://hi.baidu.com/andywangc ...
- Matlab中imagesc用法
来源:https://ww2.mathworks.cn/help/matlab/ref/imagesc.html?searchHighlight=imagesc&s_tid=doc_srcht ...
- 搭建Leanote私有云服务器
安装流程 安装Golang 安装Leanote 安装Mongodb 配置Leanote 初始化Mongodb数据 运行Leanote 安装Golang # 下载go1.14.4.linux-amd64 ...
- 在自己电脑上查看git远程分支列表比实际云端的远程分支要多一些
问题 最近打开一个很久没有打开过的项目,使用git branch -a查看了一下所以分支,其中有些远程分支没有什么用了 于是准备去gitlab上删除它,结果到gitlab上发现没有这些分支,猜测是自己 ...
- 【Zabbix】在CentOS 7上搭建Zabbix服务,收集Windows客户端计数器性能数据(含过程中遇到的问题解决方法)
1.环境 1.1.关闭防火墙 命令:systemctl stop firewalld 或者 systemctl stop firewalld.service (备注:相应的,若要开启防火墙,将对应的& ...