捞,悬 o1 账号
查看原帖
捞,悬 o1 账号
637788
kimi0705楼主2024/10/21 09:51

Link

样例都没过...

#include <bits/stdc++.h>
using std::cout;
using std::swap;
using std::vector;
const int N = 3e4 + 10;
const int Q = 3e5 + 10;
int n, q;
int arr[N];
char c[Q][10];
int in1[Q], in2[Q];
int ans[Q];
int father[N], son[N], top[N], siz[N], id[N], dep[N], rank[N], tot;
int sum[N << 2], l[N << 2], r[N << 2];
vector<int> edge[N];
int fa[N];
int find(int x) {
   return fa[x] == x ? x : find(fa[x]);
}
bool merge(int x, int y) {
   int fx = find(x);
   int fy = find(y);
   if (fx == fy)
      return false;
   fa[fx] = fy;
   return true;
}
void dfs1(int x, int parent) {
   siz[x] = 1;
   dep[x] = dep[parent] + 1;
   father[x] = parent;
   for (int i : edge[x]) {
      if (i != parent) {
         dfs1(i, x);
         siz[x] += siz[i];
         if (siz[i] > siz[son[x]])
            son[x] = i;
      }
   }
}
void dfs2(int x, int parent) {
   top[x] = parent;
   id[x] = ++tot;
   rank[tot] = x;
   if (son[x])
      dfs2(son[x], parent);
   for (int i : edge[x]) {
      if (i != son[x] && i != father[x])
         dfs2(i, i);
   }
}
void build(int o, int L, int R) {
   l[o] = L;
   r[o] = R;
   if (L == R) {
      sum[o] = arr[rank[L]];
      return;
   }
   int mid = (L + R) >> 1;
   build(o << 1, L, mid);
   build(o << 1 | 1, mid + 1, R);
   sum[o] = sum[o << 1] + sum[o << 1 | 1];
}
int query(int o, int L, int R) {
   if (L <= l[o] && r[o] <= R)
      return sum[o];
   int mid = (l[o] + r[o]) >> 1;
   int ans = 0;
   if (L <= mid)
      ans += query(o << 1, L, R);
   if (mid < R)
      ans += query(o << 1 | 1, L, R);
   return ans;
}
void update(int o, int id, int x) {
   if (l[o] == r[o]) {
      sum[o] = x;
      return;
   }
   int mid = (l[o] + r[o]) >> 1;
   if (id <= mid)
      update(o << 1, id, x);
   else
      update(o << 1 | 1, id, x);
   sum[o] = sum[o << 1] + sum[o << 1 | 1];
}
int main() {
   scanf("%d", &n);
   for (int i = 1; i <= n; i++)
      fa[i] = i;
   for (int i = 1; i <= n; i++)
      scanf("%d", &arr[i]);
   scanf("%d", &q);
   for (int i = 1; i <= q; i++)
      scanf("%s%d%d", c[i], &in1[i], &in2[i]);

   for (int i = 1; i <= q; i++)
      if (c[i][0] == 'b')
         if (merge(in1[i], in2[i])) {
            edge[in1[i]].push_back(in2[i]);
            edge[in2[i]].push_back(in1[i]);
         }
   for (int i = 1; i <= n; i++) {
      if (fa[i] == i) {
         dfs1(i, i);
         dfs2(i, i);
      }
   }
   build(1, 1, n);

   //	for (int i = 1; i <= n; i++) {
   //		for (int j : edge[i])
   //			cout << i << ' ' << j << '\n';
   //	}
   //	cout << "father: ";
   //	for (int i = 1; i <= n; i++)
   //		cout << father[i] << ' ';
   //	cout << '\n';
   //	cout << "son: ";
   //	for (int i = 1; i <= n; i++)
   //		cout << son[i] << ' ';
   //	cout << '\n';
   //	cout << "top: ";
   //	for (int i = 1; i <= n; i++)
   //		cout << top[i] << ' ';
   //	cout << '\n';
   //	cout << "size: ";
   //	for (int i = 1; i <= n; i++)
   //		cout << siz[i] << ' ';
   //	cout << '\n';
   //	cout << "id: ";
   //	for (int i = 1; i <= n; i++)
   //		cout << id[i] << ' ';
   //	cout << '\n';

   for (int i = 1; i <= n; i++)
      fa[i] = i;
   for (int i = 1; i <= q; i++) {
      if (c[i][0] == 'b') {
         if (merge(in1[i], in2[i]))
            puts("yes");
         else
            puts("no");
      } else if (c[i][0] == 'p') {
         update(1, id[in1[i]], in2[i]);
      } else {
         if (find(in1[i]) == find(in2[i])) {
            int res = 0;
            int L = in1[i], R = in2[i];
            while (top[L] != top[R]) {
               if (dep[top[L]] < dep[top[R]])
                  swap(L, R);
               res += query(1, id[top[L]], id[L]);
               L = father[top[L]];
            }
            if (dep[top[L]] > dep[top[R]])
               swap(L, R);
            res += query(1, id[L], id[R]);
            printf("%d\n", res);
         } else {
            puts("impossible");
         }
      }
   }
}
2024/10/21 09:51
加载中...