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还比自己大的 ...
随机推荐
- 转载:关于Python3中venv虚拟环境
https://www.cnblogs.com/zhaof/p/7299025.html
- 工具请求接口参数为string类型的JSON字符串时需要加转义字符模拟测试
例如postMan传String类型的json字符串请后台接口时,需要\转义
- 解决 SecureCRT 和 SecureFX 中文乱码
引言 最近老是有小伙伴给我发消息说,下载的 SecureCRT 和 SecureFX 安装打开后连接了自己的服务器或虚拟机后会出现中文乱码,每次都要给一一回复,我倒没事,主要是有时候因为工作的原因,所 ...
- 题目:写出一条SQL语句,查询工资高于10000,且与他所在部门的经理年龄相同的职工姓名。
create table Emp( eid char(20) primary key, ename char(20), age integer check (age > 0), did char ...
- Python之路——变量
什么是变量 #变量即变化的量,核心是"变"与"量"二字,变即变化,量即衡量状态. 为什么要有变量 #程序执行的本质就是一系列状态的变化,变是程序执行的直接体现, ...
- thinkphp6.0.x 反序列化详记(一)
前言 这几天算是进阶到框架类漏洞的学习了,首当其冲想到是thinkphp,先拿thinkphp6.0.x来学习一下,体验一下寻找pop链的快乐. 在此感谢楷师傅的帮忙~ 环境配置 用composer指 ...
- TTL电平,CMOS电平,232/485电平,OC门,OD门基础知识
1.RS232电平 或者说串口电平,有的甚至说计算机电平,所有的这些说法,指得都是计算机9针串口 (RS232)的电平,采用负逻辑, -15v ~ -3v 代表1 +3v ~ +15v 代表0 2. ...
- Nuxt+Vue聊天室|nuxt仿微信App界面|nuxt.js聊天实例
一.项目简述 nuxt-chatroom 基于Nuxt.js+Vue.js+Vuex+Vant+VPopup等技术构建开发的仿微信|探探App界面社交聊天室项目.实现了卡片式翻牌滑动.消息发送/emo ...
- Verilog基础入门——Vivado工程创建(三)
Verilog基础入门--Vivado工程创建(三) Vivado是Verilog语言的一个集成环境,目前使用的版本为英文版,简单介绍一下在Vivado中创建一个工程并写入源文件 [配置] win10 ...
- 什么是 C 和 C ++ 标准库?学编程的你应该知道这些知识!
简要介绍编写C/C ++应用程序的领域,标准库的作用以及它是如何在各种操作系统中实现的. 我已经接触C++一段时间了,一开始就让我感到疑惑的是其内部结构:我所使用的内核函数和类从何而来? 谁发明了它们 ...