From d871b2b8efef10ee0a8a119d83713c21f8434968 Mon Sep 17 00:00:00 2001 From: hanyixuanten Date: Tue, 27 Oct 2026 13:01:40 +0000 Subject: [PATCH] new file: P7707.cpp --- P7707.cpp | 100 +++++++++++++++++++++++++++++++++++++ P7707.md | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+) create mode 100644 P7707.cpp create mode 100644 P7707.md diff --git a/P7707.cpp b/P7707.cpp new file mode 100644 index 0000000..15d85ee --- /dev/null +++ b/P7707.cpp @@ -0,0 +1,100 @@ +#include +#define int long long +using namespace std; +struct node {int l, r, res = 0, h;}; +const int N = 1e6 + 7; +int n, m, k, h[N], t[N]; +vector tr[N * 4]; +bool operator<(const node &a, const node &b) { return a.h < b.h; } +node operator+(const node &a, const node &b) +{ + if (!a.res) + return b; + if (!b.res) + return a; + node ret; + ret.h = max(a.h, b.h), ret.l = a.l, ret.r = b.r; + ret.res = a.res + b.res - ((a.r == b.l)?1:0); + return ret; +} +void pushup(int p) +{ + int t1 = 0, t2 = 0; + while (t1 < (int)tr[p << 1].size() || t2 < (int)tr[p << 1 | 1].size()) + { + if (t2 == (int)tr[p << 1 | 1].size() || (t1 < (int)tr[p << 1].size() && tr[p << 1][t1] < tr[p << 1 | 1][t2])) + { + if (t2) + tr[p].push_back(tr[p << 1][t1++] + tr[p << 1 | 1][t2 - 1]); + else + tr[p].push_back(tr[p << 1][t1++]); + } + else + { + if (t1) + tr[p].push_back(tr[p << 1][t1 - 1] + tr[p << 1 | 1][t2++]); + else + tr[p].push_back(tr[p << 1 | 1][t2++]); + } + } +} +void add(int p, int l, int r, int pos, int h, int t) +{ + if (l == r) + { + tr[p].push_back({t, t, 1, h}); + return; + } + int mid = (l + r) >> 1; + if (pos <= mid) + add(p << 1, l, mid, pos, h, t); + else + add(p << 1 | 1, mid + 1, r, pos, h, t); + if (r == pos) + pushup(p); +} +node query(int p, int l, int r, int lq, int rq, int h) +{ + if (lq <= l && rq >= r) + { + if (tr[p][0].h > h) + return node{0, 0, 0, 0}; + int pos = upper_bound(tr[p].begin(), tr[p].end(), node{0, 0, 0, h}) - tr[p].begin() - 1; + return tr[p][pos]; + } + int mid = (l + r) >> 1; + if (rq <= mid) + return query(p << 1, l, mid, lq, rq, h); + if (lq > mid) + return query(p << 1 | 1, mid + 1, r, lq, rq, h); + return query(p << 1, l, mid, lq, rq, h) + query(p << 1 | 1, mid + 1, r, lq, rq, h); +} +signed main() +{ + scanf("%lld%lld%lld", &n, &m, &k); + for (int i = 1; i <= n; i++) + scanf("%lld", &h[i]); + for (int i = 1; i <= n; i++) + scanf("%lld", &t[i]); + for (int i = 1; i <= n; i++) + add(1, 1, n + m, i, h[i], t[i]); + int lst = 0, cnt = n; + int l, r, x, y; + for(int i = 1; i <= m; ++i) + { + int op; + scanf("%lld", &op); + if (op == 1) + { + scanf("%lld%lld%lld", &l, &r, &x), l ^= k * lst, r ^= k * lst, x ^= k * lst; + lst = query(1, 1, n + m, l, r, x).res; + printf("%lld\n", lst); + } + else + { + scanf("%lld%lld", &x, &y), x ^= k * lst, y ^= k * lst; + add(1, 1, n + m, ++cnt, x, y); + } + } + return 0; +} \ No newline at end of file diff --git a/P7707.md b/P7707.md new file mode 100644 index 0000000..c3f5405 --- /dev/null +++ b/P7707.md @@ -0,0 +1,147 @@ +# P7707 「Wdsr-2.7」百花齐放的太阳花田 + +## 题目背景 + +> 春天到来,花儿盛开……只是这次开花比起以往多上许多,甚至所有季节的花都开了。 + +$$\kern{1pt}\tag*{\small\text{——东方花映冢}}$$ + +今年的太阳花田,因为各种各样花朵的开放而显得格外热闹。尽管这是一场有关于花的异变,但是太阳花田的主人风见幽香却格外享受由鲜花带来的五彩缤纷的花田——毕竟,向来冷清的花田因为各种妖精的活跃而变得热闹了起来。 + +幽香非常喜欢这些花朵。每朵花都有它自己的种类,也代表了一种性格。比如向日葵,比如蒲公英,比如天人菊…… + +奇怪的是,有些花朵可能会属于同一种类,但由于相关因素(比如年龄、营养等),使得每种花都有一个高度。 + +幽香非常感兴趣,因为这些花朵高高低低形形色色,使得太阳花田呈现出了别样的景色。兴致之余,幽香选取了一些花朵,希望你帮助她解决一个问题。 + +## 题目描述 + +一开始,幽香选择了太阳花田当中的 $n$ 朵花朵。每朵花有一个高度 $h_i$ ,以及它属于的类别 $t_i$ 。它们排成了一列,并且被标号为 $1,2,3\cdots n$ 。幽香有 $m$ 次操作,分为两种: + +- $\colorbox{f0f0f0}{\verb!1 l r x!}$ :考虑区间 $[l,r]$ 内的所有花朵。我们取出其中所有高度不超过 $x$ 的花朵(即 $h_i\le x$ 的花朵),**依次排列**(即不改变花朵在原序列中的顺序),可以根据它们的种类划分为若干段(比如,$\{\underline{1,}\ \underline{2,2},\underline{1,1},\underline {3,}\ \underline{4,4,4}\}$ 就能分为 $5$ 段)。幽香希望你告诉她一共有多少段。 + +- $\colorbox{f0f0f0}{\verb!2 x y!}$ :幽香挑选了一朵高度为 $x$ ,种类为 $y$ 的花朵,拼接在末尾。 + +**强制在线。** + +## 输入格式 + +- 第一行三个整数 $n,m,k$ 。$n,m$ 含义如上,而 $k$ 为**强制在线参数**。 + +- 接下来两行,第一行是 $n$ 个整数,表示 $\{h_1,h_2\cdots h_n\}$ ;第三行 $n$ 个整数,表示序列 $t_1,t_2\cdots t_n\}$ 。含义如题所示。 + +- 接下来 $m$ 行,每行首先一个整数 $op$ ,表示本次操作的种类。 + + - 如果 $op = 1$,接下来三个整数 $l',r',x'$,描述一次查询。 + + - 如果 $op = 2$,接下来两个整数 $x',y'$,表示一次修改。 + +- 在所有操作中,真正的 $l,r,x,y$ 都是输入的 $l',r',x',y'$ 异或上 $k \times last$ 后的值。其中, $last$ 表示最后一次查询的答案,初始为 $0$。 + +## 输出格式 + +- 共有若干行。对于每个操作 $1$ ,每行输出一个整数,表示答案。 + +## 输入输出样例 #1 + +### 输入 #1 + +``` +10 10 0 +6 8 5 9 6 10 2 4 8 9 +2 4 3 3 4 1 2 3 3 2 +2 2 8 +1 1 4 4 +2 1 6 +2 10 2 +1 7 9 7 +2 10 8 +2 8 4 +2 3 10 +1 5 16 5 +1 4 14 7 + +``` + +### 输出 #1 + +``` +0 +2 +5 +5 + +``` + +## 输入输出样例 #2 + +### 输入 #2 + +``` +10 20 0 +2 19 13 20 7 19 17 8 15 12 +1 2 4 3 5 3 2 4 2 2 +2 9 3 +2 17 3 +1 1 9 15 +1 1 12 3 +2 15 5 +1 6 13 6 +2 7 1 +2 20 3 +2 12 1 +2 10 1 +1 5 9 4 +1 1 7 15 +2 12 4 +1 12 12 14 +2 7 5 +1 3 18 6 +1 7 7 1 +2 8 5 +1 6 8 10 +1 14 18 4 + +``` + +### 输出 #2 + +``` +5 +1 +0 +0 +3 +0 +0 +0 +1 +0 + +``` + +## 说明/提示 + +$n'$ 表示进行所有操作后的序列长度。 + +$$ +\def\arraystretch{1.5} +\begin{array}{|c|c|c|c|}\hline +\bf{Subtask} & \bm{n',m} & \textsf{\textbf{特殊性质}} & \textsf{\textbf{分值}} \cr\hline +1 & 1\le n',m \le 10^3 & \text{无} & 10 \cr\hline +2 & 1\le n',m \le 3\times 10^5 & k=0 & 20\cr\hline +3 & 1\le n',m \le 3\times 10^5 & l=1 & 25\cr\hline +4 & 1\le n',m \le 10^5 & \text{无} & 15\cr\hline +5 & 1\le n',m \le 3\times 10^5 & \text{无} & 20\cr\hline +6 & \text{无特殊限制} & \text{时限 3s,空限 300MB} & 10\cr\hline +\end{array}$$ + +- 对于 $100\%$ 的数据: + + $1 \le n',m \le 5 \times 10 ^ 5$。 + + $1 \le h_i,t_i,x,y \le 10^9$,$1 \le l \le r \le n'$。 + + $1 \le op \le 2$,$0 \le k \le 10^3$。 + +提示:请注意常数优化。 \ No newline at end of file