首页 > 其他分享 >CF1327F AND Segments

CF1327F AND Segments

时间:2023-01-03 16:58:45浏览次数:47  
标签:ch CF1327F int Segments posr getchar

CF1327F AND Segments

这题好像有点简单。

肯定先拆位,限制转化为两种:

  • 强制 $[l_i,r_i] $全为1
  • 强制 $[l_i,r_i] $不全为1

对于第一种限制,这时候 \([l_i,r_i]\) 已经确定了,所以可以直接差分一下直接把这一部分的 \(a\) 求出来,剩下的 \(a\) 只需考虑第二种限制。

维护 \(L_i\) 表示满足最小的位置 \(p\) 使得 \([p,i)\) 可以全部为 \(1\),设 \(f_i\) 表示最后一个填的位置是 \(i\),已经满足了右端点在 \([1, i]\) 内的限制的方案数。那么转移是很简单的。

\[f_i = \sum_{L_{i - 1} < k < i} f_k \]

这个直接用前缀和维护一下就可以了。

详情

#include <cstdio>
#include <iostream>
#define LL long long
using namespace std;
template <typename T>
inline void read(T &x) {
	x = 0; int f = 0; char ch = getchar();
	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
	for(; isdigit(ch); ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
	if(f) x = ~x + 1;
}
const int N = 5e5 + 10;
const int P = 998244353;
int n, m, k;
int l[N], r[N], v[N], pos[N];
int posl[N], posr[N];
int a[N], L[N];
int sum[N], f[N];
int calc(int p) {
	for(int i = 1; i <= n; ++i) a[i] = pos[i] = 0;
	for(int i = 1; i <= m; ++i) 
		if(v[i] >> p & 1) ++a[l[i]], --a[r[i] + 1];
	for(int i = 1; i <= n; ++i)
		a[i] += a[i - 1];
	int tot = 0;
	for(int i = 1; i <= n; ++i) {
		if(a[i] == 0) pos[i] = ++tot;
		else a[i] = 1;
		a[i] += a[i - 1];
	}
	for(int i = n; i >= 1; --i) 
		if(!pos[i]) posr[i] = posr[i + 1];
		else posr[i] = pos[i];
	for(int i = 1; i <= n; ++i)
		if(!pos[i]) posl[i] = posl[i - 1];
		else posl[i] = pos[i]; 
	for(int i = 1; i <= tot; ++i) L[i] = 0;
	for(int i = 1; i <= m; ++i) {
		if(v[i] >> p & 1) continue;
		if(a[r[i]] - a[l[i] - 1] == r[i] - l[i] + 1) return 0; 
		L[posl[r[i]]] = max(L[posl[r[i]]], posr[l[i]]);
	}
	for(int i = 1; i <= tot; ++i)
		L[i] = max(L[i], L[i - 1]);
	f[0] = sum[0] = 1;
	for(int i = 1; i <= tot; ++i)
		f[i] = (sum[i - 1] - (L[i - 1] <= 0 ? 0 : sum[L[i - 1] - 1]) + P) % P,
		sum[i] = (sum[i - 1] + f[i]) % P;
	int res = 0;
	for(int i = L[tot]; i <= tot; ++i)
		res = (res + f[i]) % P;
	return res;
}
int main() {
	read(n), read(k), read(m);
	for(int i = 1; i <= m; ++i)
		read(l[i]), read(r[i]), read(v[i]);
	LL ans = 1;
	for(int p = 0; p < k; ++p)
		ans = ans * calc(p) % P;
	printf("%lld\n",ans);
}

标签:ch,CF1327F,int,Segments,posr,getchar
From: https://www.cnblogs.com/DCH233/p/17022695.html

相关文章

  • ollydbg中加载的DLL基地址确定 IDA里IDA:Edit->segments->Rebase program去设置同步
    ollydbg在工具栏E里点击,找到加载的DLL,可以看到基地址,例如下面的就是6CBE0000,IDA里IDA:Edit->segments->Rebaseprogram去设置同步即可!      好了下面是一些......
  • 1104 Sum of Number Segments
    Givenasequenceofpositivenumbers,asegmentisdefinedtobeaconsecutivesubsequence.Forexample,giventhesequence{0.1,0.2,0.3,0.4},wehave10......
  • CF1684F Diverse Segments
    本题的问题等价于删除一个区间之后是否询问的所有区间都没有相同的数对。记录\(i\)的\(minL_i\)表示包含\(i\)的区间的最小左端点\(maxR_i\)同理,每次删除\(i\)......
  • [题解]CF1327F
    首先拆位,然后考虑限制会带来什么。要求与起来是\(1\)的必须全是\(1\),差分打个标记。要求与起来是\(0\)的必须至少有一个\(0\),考虑如何计数。计数问题有可能是动态......
  • CF981E Addition on Segments
    \(\text{Solution}\)一道有思维的\(hash\)题,考虑先确定了\(r0\)的长度,那么\(r1\)的长度也就确定了,这样我们可以用\(O(|T|)\)来确定每个\(0\)和\(1\)对应的字符串,可以用字......
  • CF1156E Special Segments of Permutation
    题目链接:​​传送门​​直接枚举最大值往左右扩就过了,,*/#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<complex>#include<algorit......
  • Code Forces 652D Nested Segments(离散化+树状数组)
     NestedSegmentstimelimitpertestmemorylimitpertestinputoutputnInputn (1 ≤ n ≤ 2·105)—thenumberofsegmentsonaline.n linescontains......
  • F. Multi-Colored Segments
    F.Multi-ColoredSegmentsDmitryhas$n$segmentsofdifferentcolorsonthecoordinateaxis$Ox$.Eachsegmentischaracterizedbythreeintegers$l_i$,$r_i$......
  • 达梦dba_segments指定表名查询到的大小都包含哪些数据
    一、结论dba_segments指定表名查询到的段大小包含索引、约束、表字段数据(包含LOB字段)(1)表(不包含LOB字段)创建默认分配2个簇,1个簇用于存放表结构及字段数据,1个簇用于存放clus......
  • Shrinking Database Segments Online
    YouuseonlinesegmentshrinktoreclaimfragmentedfreespacebelowthehighwatermarkinanOracleDatabasesegment.Thebenefitsofsegmentshrinkarethe......