题目大意:有$n(n\leqslant2\times10^5)$个序列,有$m(m\leqslant2\times10^5)$个操作,分三种:

1. $M\;x\;y:$把$x$所在的序列放在$y$所在序列之后
2. $D\;x:$把$x$所在的序列从它前面断开
3. $Q\;x\;y:$询问若$x,y$在同一序列中,它们之间的元素和

题解:平衡树,合并就正常合并,注意是把$x$放到$y$后,关于找$x$所在的序列,就记录每个节点的父亲,直接向上跳父亲就可以了,在分裂时注意维护父亲。

求元素的排名就看一下它是不是它父亲的右儿子,是的话把它兄弟的大小加上。

询问就记录一个区间和即可。

卡点:

C++ Code:

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#define maxn 200010 namespace Treap {
int pri[maxn], lc[maxn], rc[maxn], fa[maxn], sz[maxn], V[maxn];
long long S[maxn];
int ta, tb, tmp, res;
inline void nw(int pos, int x) {
pri[pos] = rand();
S[pos] = V[pos] = x;
lc[pos] = rc[pos] = fa[pos] = 0;
sz[pos] = 1;
}
inline int update(int rt) {
const int lc = Treap::lc[rt], rc = Treap::rc[rt];
if (lc) fa[lc] = rt;
if (rc) fa[rc] = rt;
sz[rt] = sz[lc] + sz[rc] + 1;
S[rt] = S[lc] + S[rc] + V[rt];
return rt;
}
void split(int rt, int k, int &x, int &y) {
if (!rt) x = y = 0;
else {
if (sz[lc[rt]] >= k) {
split(lc[rt], k, x, lc[rt]);
fa[x] = fa[rt] = 0;
y = update(rt);
} else {
split(rc[rt], k - sz[lc[rt]] - 1, rc[rt], y);
fa[rt] = fa[y] = 0;
x = update(rt);
}
}
}
int merge(int x, int y) {
if (!x || !y) return x | y;
if (pri[x] < pri[y]) { rc[x] = merge(rc[x], y); return update(x); }
else { lc[y] = merge(x, lc[y]); return update(y); }
}
inline int gtrnk(int x) {
res = sz[lc[x]] + 1;
while (x) {
if (rc[fa[x]] == x) res += sz[lc[fa[x]]] + 1;
x = fa[x];
}
return res;
}
inline int gtrt(int x) {
while (fa[x]) x = fa[x];
return x;
} inline void Merge(int x, int y) {
x = gtrt(x), y = gtrt(y);
if (x == y) return ;
merge(y, x);
}
inline void Split(int x) {
int rk = gtrnk(x); x = gtrt(x);
split(x, rk - 1, ta, tb);
}
inline void query(int x, int y) {
int root = gtrt(x);
if (root != gtrt(y)) {
puts("-1");
return ;
}
int rkx = gtrnk(x), rky = gtrnk(y);
if (rkx > rky) std::swap(rkx, rky);
split(root, rky, ta, tb);
split(ta, rkx - 1, ta, tmp);
printf("%lld\n", S[tmp]);
merge(ta, merge(tmp, tb));
}
} int n, m; int main() {
srand(20040826);
scanf("%d%d", &n, &m);
for (int i = 1, x; i <= n; ++i) {
scanf("%d", &x);
Treap::nw(i, x);
}
while (m --> 0) {
char op;
int x, y;
scanf("%1s%d", &op, &x);
switch (op) {
case 'M':
scanf("%d", &y);
Treap::Merge(x, y);
break;
case 'D':
Treap::Split(x);
break;
case 'Q':
scanf("%d", &y);
Treap::query(x, y);
}
}
return 0;
}

  

[洛谷P4847]银河英雄传说V2的更多相关文章

  1. P4847 银河英雄传说V2 题解(Splay)

    题目链接 P4847 银河英雄传说V2 解题思路 我天哪!!!\(splay\)在\(rotate\)的时候先\(upd(y)\)再\(upd(x)\)!!以后不能再因为这个\(WA\)一晚上了!!! ...

  2. NOI2002 洛谷 P1196 银河英雄传说

    神奇的并查集问题 题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩 ...

  3. 洛谷—— P1196 银河英雄传说

    https://www.luogu.org/problem/show?pid=1196 题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始 ...

  4. 洛谷 [p1196] 银河英雄传说

    所谓带权并查集 本题所求的不止是两个编号之间是否有关系,还要求两个编号之间有什么关系,这就要求我们维护多个数组,fa[]数组维护两个编号之间的连通性,dis[]维护编号为i的战舰到fa[i]之间的距离 ...

  5. 洛谷P1196 银河英雄传说

    大意:你有30000个队列,第i个队列中只有i 有T个操作,1,把某个队列头接到另一个队列尾. 2,问两个元素之间的距离. 本题主要有三种解法. ①带权并查集. 具体来说就是,并查集维护当前集合的大小 ...

  6. NOI2002_ Galaxy银河英雄传说86

    NOI2002_ Galaxy银河英雄传说86     公元五八○一年,地球居民迁移至金牛座α第二行星,:宇宙历七九九年,银河系的两大军事集团在巴米利恩星:杨威利擅长排兵布阵,巧妙运用各种战术屡次以少 ...

  7. NOI2002 银河英雄传说

    P1196 银河英雄传说 367通过 1.1K提交 题目提供者该用户不存在 标签并查集NOI系列2001(或之前) 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 莱因哈特什么鬼? 私人代码 ...

  8. [洛谷P1338] 末日的传说

    洛谷题目链接:末日的传说 题目描述 只要是参加jsoi活动的同学一定都听说过Hanoi塔的传说:三根柱子上的金片每天被移动一次,当所有的金片都被移完之后,世界末日也就随之降临了. 在古老东方的幻想乡, ...

  9. 加权并查集(银河英雄传说,Cube Stacking)

    洛谷P1196 银河英雄传说 题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展.宇宙历七九九年,银河系的两大军事集团在 ...

随机推荐

  1. nested class 例子

    #include<iostream> using namespace std; /* start of Enclosing class declaration */ class Enclo ...

  2. 「日常训练」 Longest Run on a Snowboard (UVA-10285)

    题意 其实就是一条二维的LIS,但是还是做的一愣一愣的,多努力. 考虑$dp[i][j]$为从(i,j)出发的二维LIS的最大值,那么$dp[i][j]=max\{dp[i−di[k]][j−dj[k ...

  3. cf#516B. Equations of Mathematical Magic(二进制,位运算)

    https://blog.csdn.net/zfq17796515982/article/details/83051495 题意:解方程:a-(a^x)-x=0 给出a的值,要求计算解(非负)的个数 ...

  4. Error -26377: No match found for the requested parameter

    Error -26377: No match found for the requested parameter

  5. Linux命令大全(非常全,史上最全)

    最近学习Linux,最大的体验就是它的很多东西都需要由命令来进行控制,下面是我总结的一些命令,供大家参考: 系统信息   arch 显示机器的处理器架构 uname -m 显示机器的处理器架构 una ...

  6. ConfigHelpers

    --默认值可以不传 local ConfigHelpers = {} --设置物体高亮 target:设置对象 isLigth:是否高亮 seeThrough:是否穿透(默认为true,穿透) sta ...

  7. C++11 type_traits 之is_same源码分析

    请看源码: template<typename _Tp, _Tp __v> struct integral_constant { static const _Tp value = __v; ...

  8. leetcode-单词探索

    单词搜索     给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格.同一个单元格内的字母 ...

  9. [SHELL]shell中变量的使用

    1.输出变量 : #! /bin/bash my_var=BOB echo $my_var echo "hi,$my_var" echo "the price is \$ ...

  10. 【MFC】VS2017新建完MFC后,没有界面,只有代码

    问题描述:双击.rc文件后提示在另一个编辑器中打开 解决方法整合: 1----- 打开工程之前先把.rc文件改个名称,然后打开工程双击解决方案管理器的.rc文件, 会显示"载入失败" ...