首页 > 其他分享 >P6492 题解

P6492 题解

时间:2024-04-22 14:24:31浏览次数:28  
标签:fr int 题解 lk tl P6492 fl rk

P6492 [COCI2010-2011#6] STEP - 洛谷

题目大意:维护一段 01 串,支持单点修改,每次修改后求最长的「\(\texttt{01010101}\dots\)」 的长度。

下文把 「\(\texttt{01010101}\dots\)」称为「合法区间」,\(k\) 为区间 \([l, r]\) 编号,\(lk, rk\) 为 \([l, r]\) 左右子区间编号。

考虑用线段树进行维护。我们用 \(fl(k), fr(k)\) 别表示区间 \([l, r]\) 的 01 情况,\(tl(k), tr(k)\) 分别表示区间 \([l, r]\) 中 \(l,r\) 在内的合法区间的最大长度,\(t(k)\) 表示区间 \([l, r]\) 的合法区间的最大长度。

则合并时:

  • \(fl(k) = fl(lk), fr(k) = fr(rk)\)。
  • 如果 \(fr(lk) \ne fl(rk)\) 则区间可以合并,\(t(k) = \max \left \{ t(lk), t(rk), tr(lk) + tl(rk) \right \}\);否则 \(t(k) = \max \left \{ t(lk), t(rk) \right \}\)。
  • 如果 \(tl(k)\) 等于区间长度且合法区间可以合并,则 \(tl(k) = tl(lk) = tl(rk)\),否则 \(tl(k) = tl(lk)\)。\(tr(k)\) 同理。

更新时只反转 \(fl, fr\) 即可。时间复杂度 \(O(n \log n)\)。

#include <iostream>  
#include <cstdio>  
#include <queue>  
using namespace std;  
  
const int N = 200010, N4 = N * 4;  
int n, q;  
int tr[N4], tl[N4], fl[N4], fr[N4], t[N4];  
  
void build(int l, int r, int k) {  
    if(l == r) {  
        fl[k] = fr[k] = 0;  
        t[k] = tl[k] = tr[k] = 1;  
        return;  
    }  
    int mid = (l + r) >> 1, lk = k << 1, rk = lk | 1;  
    build(l, mid, lk); build(mid + 1, r, rk);  
    fl[k] = fl[lk], fr[k] = fr[rk];  
    t[k] = max(t[lk], t[rk]);  
    if(fr[lk] != fl[rk]) t[k] = max(t[k], tl[rk] + tr[lk]);  
    tl[k] = tl[lk], tr[k] = tr[rk];  
    if(tl[lk] == mid - l + 1 && fr[lk] != fl[rk]) tl[k] += tl[rk];  
    if(tr[rk] == r - mid && fr[lk] != fl[rk]) tr[k] += tr[lk];  
}  
  
void upd(int l, int r, int k, int L, int R) {  
    if(L <= l && r <= R) {  
        fl[k] = !fl[k]; fr[k] = !fr[k];  
        return;  
    }  
    int mid = (l + r) >> 1, lk = k << 1, rk = lk | 1;  
    if(L <= mid) upd(l, mid, lk, L, R);  
    if(mid < R) upd(mid + 1, r, rk, L, R);  
    fl[k] = fl[lk], fr[k] = fr[rk];  
    t[k] = max(t[lk], t[rk]);  
    if(fr[lk] != fl[rk]) t[k] = max(t[k], tl[rk] + tr[lk]);  
    tl[k] = tl[lk], tr[k] = tr[rk];  
    if(tl[lk] == mid - l + 1 && fr[lk] != fl[rk]) tl[k] += tl[rk];  
    if(tr[rk] == r - mid && fr[lk] != fl[rk]) tr[k] += tr[lk];  
}  
  
int main() {  
    scanf("%d%d", &n, &q);  
    build(1, n, 1);  
    while(q--){  
        int x; scanf("%d", &x);  
        upd(1, n, 1, x, x);  
        printf("%d\n", t[1]);  
    }  
    return 0;  
}

标签:fr,int,题解,lk,tl,P6492,fl,rk
From: https://www.cnblogs.com/Running-a-way/p/18150553

相关文章

  • atcoder regular 176 (ARC176) A、B题解
     A很容易有一个错误想法,就是行从1~n,列从1~n拿,这样,第三个样例,最后,第7行,第7列,需要都增加两个数,但是(7,7)这个位置只能有一个数。我的做法是优先队列/set队列,每次选择行、列之中当前已经有的数目最少的(这样它们最需要添加),这样能保证,行列需要添加的,不会出现只能选择多个行列一样的......
  • P1637 题解
    一道绿写2.5h,我是什么效率哥。Solution提供一种不使用线段树/树状数组的方法。前置知识:分治,二分,前缀和。考虑分治。我们假设有一个分治函数solve(l,r)可以统计区间\([l,r]\)中的thair。对于一个区间\([l,r]\)中的thair\(=\{a_i,a_j,a_k|i<j<k\) 且\(a_......
  • P8207 [THUPC2022 初赛] 最小公倍树 题解
    题目大意有编号为\([L,R]\)区间的点,连接两个点\(x,y\)边权的为\(LCM(x,y)\),求这张图的最小生成树。\[1\leqL\leqR\leq10^6,R-L\leq10^5\]解题思路我们有一个结论:对于张图\(G\)中的一个生成子图\(E\),\(E\)之中的一条边\(k\)如果不在\(E\)最小生成树中,那么\(......
  • P7431【THUPC2017】小 L 的计算题 (牛顿恒等式)(分治NTT)(多项式求逆)题解
    知识点涉及:牛顿恒等式,分治\(NTT\),多项式求逆。这道题有一个推式子之后分治\(NTT+Ln+Exp\)的做法,不过也有一个不用\(Ln+Exp\)的做法(理论常数要小点,实际差不多)。题解:这道题可以牛顿恒等式直接推出一个非常好写的东西。首先看一下牛顿恒等式的描述:对于\(n\)次多项式\(A(......
  • CF1067E Random Forest Rank 题解
    这道题涉及了组合分析和概率。本质上,当以一定的概率从给定的树中删除边时,您需要找到结果林的邻接矩阵的期望秩。要解决这个问题,可以使用动态规划。我们用\(f(u,v)\)表示当删除边\((u,v)\)时,由以顶点\(v\)为根的子树中的顶点形成的林的期望秩。这里,\(u\)和\(v\)是树中的......
  • 2024年GPLT团体程序设计比赛L2-D吉利矩阵题解
    只能说比赛时前期做得太慢了,后面导致题目只能捞点分数(IOI赛制),当时这道题是我不剪枝DFS拿了4分,压线拿铜牌!考完试一做,发现是个大水题(bushi)主要原理:DFS(深度优先搜索)+剪枝名言:学搜索核心就是学剪枝废话不说了,见代码点击查看代码//原理:DFS+剪枝#include<bi......
  • Atcoder ABC 350 全题解
    题外话别以为博主之前几场ABC都咕咕咕了,最近状态不好,这次ABC终于回来了(也有可能是题目变容易了,有图为证)P.S.请耐心看到最后!!否则后果自负!!!AB这年头谁不会AB啊当然有。不学OI的人。C考虑选择排序,依次将$1,2,3\cdots$与它们应该在的位置进行交换。那如果真的......
  • 题解:CF17D Notepad
    由于首位不能是\(0\),因此首位有\(b-1\)种可能性。其他\(n-1\)位有\(b^{n-1}\)种可能。因此这些数总计\((b-1)b^{n-1}\)每页\(c\)个数,求最后一页有多少个数,即求\(\text{ans}=(b-1)b^{n-1}\quad\bmodc\)注意到题目中\(b,n\)都非常大,采用扩展欧拉定理进行降......
  • [ZJOI2019] 语言 题解
    不愧是\(ZJOI\),《最可做的一道题》都让人一头雾水……首先将问题转化到链上。可以将总共的组数转化为每个点可以到达的城市。明显给每个点建一棵动态开点线段树,维护可以和他通商的点。很明显,可以通商的点的标号连续的一段。我们可以将可以将每一次传播语言的工作当作区间修改......
  • 【题解】[NOIP2001 普及组] 装箱问题
    [NOIP2001普及组]装箱问题这是一道动态规划题。那就先定义状态吧(这里用的是一维滚动数组)。$f[j]$代表当我有$j$这么多容量可以用时,能装的最大重量是多少。好,状态定义好了再想状态转移方程。$f[j]$可以从哪里转移过来呢?想一想,当我们循环到第$i$个物品时,我们面临两个......