zoukankan      html  css  js  c++  java
  • CF1327F AND Segments

    链接

    Description

    要求构造满足下列条件的长度为 (n) 的序列 (a) 的个数:

    • 每个数值域在 ([0, 2 ^ k))
    • (m) 个限制条件 (l, r, x),需要满足 (a_l ext{and} a_{l+1} ext{and} ... ext{and} a_{r} = x)。 (二进制按位与)

    (n, m le 5 · 10^5)

    Solution

    二进制表示,每个数都是一个 (k) 位的 (01) 串。按位与限制,不同位互不影响,考虑分别做再乘法原理乘起来。

    现在问题转化为了,构造长度为 (n)(01) 串,有 (m) 个限制。

    • 要么为一段区间都是 (1)
    • 或是一段区间必须有一个 (0)

    不妨枚举 (0) 的出现位置。

    状态设计

    (f_i) 表示前 (i) 个位置,第 (i) 个位置为 (0)([1, i]) 区间内包含的所有区间条件已经满足的方案数。

    状态转移

    • 如果第 (i) 位必须填 (1)(这个用差分 (O(n)) 预处理),那么 (f_i = 0)。做完这步,第一个限制肯定满足,因为填 (0) 的机会全部被否认掉了。
    • 否则,枚举上一个 (0) 的位置 (0 le j < i),即 ((j, i)) 区间全部填 (1)(f_i = sum f_j)。为了满足第二个条件,那么 ((j, i)) 区间必然不能完全包含第二个限制的任何一个区间,即 (j) 必须 (ge max(l)),其中 (r le i - 1) 的。

    优化

    对于 (f_i = sum f_j)。发现 (j) 所取的是一个滑动窗口 ([max(l), i - 1])。即左右端点都是不降的,这样搞一个变量动态维护这个和即可。

    初始状态:(f_0 = 1)
    答案:(sum f_{j}^{n})(最后一波连续的 (1) 里也不能包含第二个限制中的任意区间)

    时间复杂度

    (O(kn))

    Code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    typedef long long LL;
    
    const int N = 500005, P = 998244353;
    
    int n, K, m, ans = 1;
    int cnt[N], pre[N], f[N];
    int L[N], R[N], X[N];
    
    int inline solve(int w) {
    	memset(f, 0, sizeof f);
    	memset(cnt, 0, sizeof cnt);
    	memset(pre, 0, sizeof pre);
    	for (int i = 1; i <= m; i++) {
    		if (X[i] >> w & 1) cnt[L[i]]++, cnt[R[i] + 1]--;
    		else pre[R[i]] = max(pre[R[i]], L[i]);
    	}
    	for (int i = 1; i <= n; i++) cnt[i] += cnt[i - 1];
    	f[0] = 1;
    	int s = 1, j = 0;
    	for (int i = 1; i <= n; i++) {
    		if (!cnt[i]) f[i] = s;
    		(s += f[i]) %= P;
    		while (j < pre[i]) s = ((LL)s - f[j++] + P) % P;
    	}
    	int res = 0;
    	for (int i = j; i <= n; i++) (res += f[i]) %= P;
    	return res;
    }
    
    int main() { 
    	scanf("%d%d%d", &n, &K, &m);
    	for (int i = 1; i <= m; i++) scanf("%d%d%d", L + i, R + i, X + i);
    	for (int k = 0; k < K; k++) ans = (LL)ans * solve(k) % P;
    	printf("%d
    ", ans); 
    }
    
  • 相关阅读:
    纯JavaScript实现HTML5 Canvas六种特效滤镜
    玩转html5 的 canvas画图
    为什么 ++[[]][+[]]+[+[]] = 10?
    作用域和闭包
    7 个令人惊讶的 JavaScript “特
    60个有用css代码片段
    函数
    数组
    我们为什么要尝试前后端分离
    javascript面向对象——构造函数和原型对象
  • 原文地址:https://www.cnblogs.com/dmoransky/p/12730591.html
Copyright © 2011-2022 走看看