题目
题目描述
给定一个长度为 n 的字符序列 a,初始时序列中全部都是字符 L。
有 q 次修改,每次给定一个 x,若$$ a_{x}$$ 为 L,则将 $$a_{x}$$ 修改成 R,否则将 $$a_{x}$$ 修改成 L。
对于一个只含字符 L,R 的字符串 ss,若其中不存在连续的 L 和 R,则称 s 满足要求。
每次修改后,请输出当前序列 a 中最长的满足要求的连续子串的长度。
输入格式
第一行有两个整数,分别表示序列的长度 n 和修改操作的次数q。
接下来 q 行,每行一个整数,表示本次修改的位置x。
输出格式
对于每次修改操作,输出一行一个整数表示修改 a 中最长的满足要求的子串的长度。
输入输出样例
说明/提示
数据规模与约定
对于全部的测试点,保证 1≤n,q≤2×105,1 ≤ x ≤ n。
说明
题目译自 COCI2010-2011 CONTEST #6 T5 STEP,翻译来自 @一扶苏一。
思考
这个题其实和区间和区别并不大,只是把求和的push_up操作改为求最长的连续符合条件的串即可。
分左,中,右三部分考虑。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| #include <bits/stdc++.h>
using namespace std;
inline long long read() { long long x = 0; int f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); } return x * f; } void write(const int& x) { if (!x) { putchar('0'); return; } char f[100]; int tmp = x; if (tmp < 0) { tmp = -tmp; putchar('-'); } int s = 0; while (tmp > 0) { f[s++] = tmp % 10 + '0'; tmp /= 10; } while (s > 0) { putchar(f[--s]); } }
const int MAXN = 1000090;
bool nums[MAXN]; long long totN; long long totDO;
struct Node { long long lvalue; long long rvalue; long long midvalue; long long l, r; Node* lch, * rch; inline void push_up() { lvalue=lch->lvalue; rvalue=rch->rvalue; if (nums[lch->r]!=nums[rch->l]) { if (lch->lvalue==(lch->r-lch->l+1)) { lvalue+=rch->lvalue; } if (rch->rvalue==(rch->r-rch->l+1)) { rvalue+=lch->rvalue; } } midvalue=max(nums[lch->r]!=nums[rch->l]?lch->rvalue+rch->lvalue:0,max(lch->midvalue,rch->midvalue)); } Node(const long long L, const long long R) { l = L; r = R; if (l==r) { lch = NULL; rch = NULL; lvalue=rvalue=midvalue=1; } else { long long mid = (l + r) >> 1; lch = new Node(L, mid); rch = new Node(mid + 1, R); push_up(); } } inline void update(const long long w) { if (l==r) { return; } if (lch->r>=w) { lch->update(w); } else { rch->update(w); } push_up(); } };
int main() { totN=read(); totDO=read(); Node *root=new Node(1,totN); for (int i = 1; i <= totDO; ++i) { auto tempX=read(); nums[tempX]^=1; root->update(tempX); write(root->midvalue); putchar('\n'); } return 0; }
|