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还比自己大的 ...
随机推荐
- HAProxy安装配置
概念 HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案. HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要 ...
- ZooKeeper 【不仅仅是注册中心,你还知道有哪些?】
什么是 ZooKeeper Apache ZooKeeper 是一个开源的实现高可用的分布式协调服务器.ZooKeeper是一种集中式服务,用于维护配置信息,域名服务,提供分布式同步和集群管理.所有这 ...
- websocket+sockjs+stompjs详解及实例
最近有项目需求要用到websocket,刚开始以为很简单,但是随着遇到问题,深入了解,才知道websocket并不是想象中的那么简单,这篇文章主要是考虑websocket在客户端的使用. 1.http ...
- React学习小记--setState的同步与异步
react中,state不能直接修改,而是需要使用setState()来对state进行修改,那什么时候是同步而什么时候是异步呢? 基础代码: setCounter = (v) => { thi ...
- 协同过滤 Collaborative Filtering
协同过滤 collaborative filtering 人以类聚,物以群分 相似度 1. Jaccard 相似度 定义为两个集合的交并比: Jaccard 距离,定义为 1 - J(A, B),衡量 ...
- pytorch和tensorflow的爱恨情仇之参数初始化
pytorch和tensorflow的爱恨情仇之基本数据类型 pytorch和tensorflow的爱恨情仇之张量 pytorch和tensorflow的爱恨情仇之定义可训练的参数 pytorch版本 ...
- Python实现的数据结构与算法之队列详解
本文实例讲述了Python实现的数据结构与算法之队列.分享给大家供大家参考.具体分析如下: 一.概述 队列(Queue)是一种先进先出(FIFO)的线性数据结构,插入操作在队尾(rear)进行,删除操 ...
- 14.深入k8s:kube-proxy ipvs及其源码分析
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 源码版本是1.19 这一篇是讲service,但是基础使用以及基本概念由于官方实在是写的 ...
- Linux 下 svn 场景实例及常用命令详解
一.SVN使用场景实例 问题: 在使用svn做为版本控制系统的软件开发中,经常会有这样的需求:在工作复本目录树的不同目录中增加了很多文件,但未纳入版本控制系统,这时如果使用svn add命令一个一个的 ...
- Springboot项目集成JPush极光推送(Java SDK)
1.由于项目的需求,需要在Android APP上实现消息推送功能,所以引用了极光推送(官网:https://www.jiguang.cn/, 文档:http://docs.jiguang.cn/) ...