<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      題解:Luogu P13129 [Ynoi Easy Round 2019] 有馬加奈

      題意

      給定一棵 \(n\) 個點的樹,節點 \(i\) 上有 \((a_i,b_i)\) 二元組,初始時為 \((0,0)\)\(q\) 次操作:

      1. 給定 \(x,c\),設當前是第 \(t\) 次操作,對于 \(x\) 到根節點的路徑上的每個點 \(i\),若 \(a_i\neq c\) 則令 \((a_i,b_i)\leftarrow (c,t)\),否則不變。
      2. 給定 \(x\),查詢 \((a_x,b_x)\)

      \(1\leq n,q\leq 10^6\)

      題解

      我好菜啊。

      對于每個二元組 \((a_i,b_i)\),把 \(a_i\) 視作顏色,那么對于某個時刻 \(t\)\(b_i\) 的就是最小的時刻使得點 \(i\)\([b_i,t]\) 時刻內,顏色始終是 \(a_i\)

      離線,把每個操作 \(1\) 掛在 \(x\) 上,DFS 整棵樹轉化為維護子樹內信息。

      對每個點在時間軸上開一個動態開點線段樹,節點 \([l,r]\) 維護 \(col\) 表示該點在 \(r\) 時刻的顏色,\(st\) 表示最小的時刻使得該點在 \([st,r]\) 時刻內,顏色始終是 \(col\)\(same\) 表示 \(st\) 是否等于 \(l\),即該點是否在時間區間內保持同色。節點很容易 \(\mathcal{O}(1)\) 合并。

      DFS 到一個點的時候,加入當前點的修改操作,然后和兒子節點的線段樹做線段樹合并即可。查詢時刻 \(t\) 的二元組只需在線段樹上做前綴查詢即可。

      時間復雜度 \(\mathcal{O}(q\log{q})\)

      被樹剖吊打了。

      代碼

      #include <iostream>
      #include <vector>
      
      using namespace std;
      
      #define lowbit(x) ((x) & -(x))
      #define chk_min(x, v) (x) = min((x), (v))
      #define chk_max(x, v) (x) = max((x), (v))
      typedef long long ll;
      typedef pair<int, int> pii;
      const int N = 1e6 + 5, N2 = N << 3;
      
      namespace IO {
      	const int S = 1 << 24, lm = 1 << 23;
      	char bi[S + 5], bo[S + 5], *p1 = bi, *p2 = bi, *p3 = bo, ch;
      	int s, bts, szo;
      	inline char gc() { return p1 == p2 && (p2 = (p1 = bi) + fread(bi, 1, 1 << 23, stdin), p1 == p2) ? EOF : *p1++; }
      	inline ll rd() {
      		s = 1, bts = 0; char ch;
      		while (ch = gc(), (ch < '0'));
      		ll x = ch ^ 48;
      		while (ch = gc(), (ch >= '0')) x = (x << 3) + (x << 1) + (ch ^ 48);
      		return s == 1 ? x : -x;
      	}
      }
      using IO::rd;
      
      int n, q, rt[N], fa[N];
      bool vis[N];
      pii ans[N];
      struct Op { int t, c; };
      vector<Op> ops[N];
      vector<int> qr[N];
      
      struct Node {
          int st, col;
          bool same;
          Node(int s = 0, int c = 0, bool sm = 1) : st(s), col(c), same(sm) {}
          Node operator+(const Node &x) const {
              if (!col) return x;
              if (!x.col) return *this;
              if (col == x.col && x.same) return *this;
              return {x.st, x.col, 0};
          }
      };
      struct SegTree {
          int tot, ls[N2], rs[N2];
          Node nodes[N2];
          inline void push_up(int p) { nodes[p] = nodes[ls[p]] + nodes[rs[p]]; }
          inline void upd(int &p, int l, int r, int x, int c) {
              if (!p) p = ++tot;
              if (l == r) return nodes[p] = {x, c, 1}, void();
              int mid = l + r >> 1;
              x <= mid ? upd(ls[p], l, mid, x, c) : upd(rs[p], mid + 1, r, x, c);
              push_up(p);
          }
          inline Node query(int p, int l, int r, int x, int y) {
              if (!p) return {};
              if (x <= l && y >= r) return nodes[p];
              int mid = l + r >> 1;
              Node res;
              if (x <= mid) res = query(ls[p], l, mid, x, y);
              if (y > mid) res = res + query(rs[p], mid + 1, r, x, y);
              return res;
          }
          inline int merge(int p, int q, int l, int r) {
              if (!p || !q) return p | q;
              int mid = l + r >> 1;
              ls[p] = merge(ls[p], ls[q], l, mid), rs[p] = merge(rs[p], rs[q], mid + 1, r);
              return push_up(p), p;
          }
      } sgt;
      
      int main() {
          ios::sync_with_stdio(0), cin.tie(0);
          n = rd(), q = rd();
          for (int i = 2; i <= n; ++i) fa[i] = rd();
          for (int i = 1; i <= q; ++i) {
              int op = rd(), x = rd(), c;
              if (op == 1) ops[x].push_back({i, c = rd()});
              else qr[x].push_back(i), vis[i] = 1;
          }
          for (int i = n; i; --i) {
          	int x = i;
          	for (Op &op : ops[x]) sgt.upd(rt[x], 1, q, op.t, op.c);
          	Node res;
          	for (int t : qr[x]) res = sgt.query(rt[x], 1, q, 1, t), ans[t] = {res.col, res.st};
          	if (fa[x]) rt[fa[x]] = sgt.merge(rt[fa[x]], rt[x], 1, q);
          }
          for (int i = 1; i <= q; ++i) if (vis[i]) cout << ans[i].first << ' ' << ans[i].second << '\n';
          return 0;
      }
      
      posted @ 2025-08-25 21:27  P2441M  閱讀(13)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久精品色一情一乱一伦| 国产办公室秘书无码精品99| 久久国产精品不只是精品| 久久综合干| 亚洲一区久久蜜臀av| 亚洲av熟女国产一二三| av 日韩 人妻 黑人 综合 无码| 亚洲精品一区二区口爆| 亚洲第一国产综合| 成人爽A毛片在线视频淮北| 欧美 亚洲 中文 国产 综合| 亚洲国产综合一区二区精品| 日韩av日韩av在线| 国产一区二区三区乱码| 蜜桃av亚洲精品一区二区| 国产福利在线观看免费第一福利| 国产乱码精品一区二区三区中文| 亚洲无人区一区二区三区| 国产不卡一区不卡二区| 欧美综合天天夜夜久久| 人人妻碰人人免费| 日本一道一区二区视频| 霍林郭勒市| 亚洲精品天堂在线观看| 免费播放一区二区三区| 中文文字幕文字幕亚洲色| 天啦噜国产精品亚洲精品| 欧美日韩亚洲国产| av天堂久久精品影音先锋| 人妻少妇偷人精品免费看| 亚洲高清WWW色好看美女| 日本一区二区中文字幕久久| 国产成人精品三级麻豆| 色综合五月伊人六月丁香| 玩弄丰满少妇人妻视频| 成人国产精品一区二区网站公司| 国产精自产拍久久久久久蜜| 亚洲国产成人字幕久久| 精品无码国产污污污免费| 日本电影一区二区三区| 国产精品国产三级国快看|