洛谷4847 银河英雄传说(LCT+LCSPLAY)
QWQ硬是把一个\(splay\)好题,做成了\(LCT\)
首先,根据题目性质,我们可以发现序列之间是具有前后性质的。
那么,我们就不可以进行\(makeroot\)等操作。
我们定义\(findroot(x)表示x所在splay最前面的点(深度最小的点)\)
\(findymh(x)表示x所在splay最后面的点(深度最大的点)\)
对于1操作,我们只需要让前面序列最后面的点,连接到后面序列最前面的点,然后\(access(findymh(x))\)
对于2操作,我们直接\(splay\)到根,然后断开和左儿子的联系
对于\(3\)操作,我们可以分别splay到跟,然后计算\(val_{1~y} -val_{1~x}\)
全程不要打乱顺序QWQ
上代码
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#define int long long
using namespace std;
inline int read()
{
  int x=0,f=1;char ch=getchar();
  while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
  while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  return x*f;
}
const int maxn = 5e5+1e2;
int ch[maxn][3];
int fa[maxn],rev[maxn];
int n,m;
int st[maxn];
int sum[maxn];
int val[maxn];
int son(int x)
{
	if (ch[fa[x]][0]==x) return 0;
	else return 1;
}
bool notroot(int x)
{
	return ch[fa[x]][0]==x || ch[fa[x]][1]==x;
}
void update(int x)
{
	sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+val[x];
}
void rotate(int x)
{
    int y=fa[x],z=fa[y];
    int b=son(x),c=son(y);
    if (notroot(y)) ch[z][c]=x;
    fa[x]=z;
    ch[y][b]=ch[x][!b];
    fa[ch[x][!b]]=y;
    ch[x][!b]=y;
    fa[y]=x;
    update(y);
    update(x);
}
void splay(int x)
{
	while (notroot(x))
	{
		//cout<<1<<endl;
		int y=fa[x],z=fa[y];
		int b=son(x),c=son(y);
		if (notroot(y))
		{
			if (b==c) rotate(y);
			else rotate(x);
		}
		rotate(x);
	}
	update(x);
}
void access(int x)
{
	for (int y=0;x;y=x,x=fa[x])
	{
		splay(x);
		ch[x][1]=y;
		update(x);
	}
}
int findroot(int x)
{
	splay(x);
	while (ch[x][0])
	{
		x=ch[x][0];
		//cout<<x<<endl;
	}
	return x;
}
int findymh(int x)
{
	splay(x);
	while (ch[x][1])
	{
		x=ch[x][1];
	}
	return x;
}
void link(int x,int y)
{
	int xx = findroot(x);
	int xxx = findymh(x);
	int yy = findymh(y);
  splay(xx);
  fa[xx]=yy;
  //ch[findymh(y)][1]=findroot(x);
  access(findymh(x));
  //splay(findymh(x));
}
void cut(int x)
{
	splay(x);
	fa[ch[x][0]]=0;
	ch[x][0]=0;
	update(x);
}
signed main()
{
   n=read(),m=read();
   for (int i=1;i<=n;i++) val[i]=read();
   for (int i=1;i<=m;i++)
   {
      char s[10];
      int ans=0;
      scanf("%s",s+1);
      if (s[1]=='M')
      {
      	 int x=read(),y=read();
      	 if (findroot(x)==findroot(y)) continue;
      	 link(x,y);
	  }
	  if (s[1]=='D')
	  {
	  	int x=read();
	  	cut(x);
	  }
	  if (s[1]=='Q')
	  {
	  	 int x=read(),y=read();
	  	 if (findroot(x)!=findroot(y))
		   {
		   cout<<-1<<"\n";
		   continue;
		 }
	  	 int ymh = findroot(x);
	     splay(ymh);
	     splay(x);
	     ans=ans-sum[ch[x][0]];
	    // access(y);
	     splay(y);
	     ans=ans+sum[ch[y][0]]+val[y];
	     //ans=ans+val[x];
	     if (ans<=0)
	     {
	     	ans=0;
	     	 //splay(ymh1);
		    // access(y);
	         splay(y);
	         ans=ans-sum[ch[y][0]];
	         //access(x);
	         splay(x);
	         ans=ans+sum[ch[x][0]]+val[x];
	         //ans=ans+val[y];
		 }
		 splay(ymh);
		 //access(oo);
		 cout<<ans<<"\n";
	  }
   }
   return 0;
}
												
											洛谷4847 银河英雄传说(LCT+LCSPLAY)的更多相关文章
- 洛谷P3950 部落冲突 [LCT]
		
题目传送门 部落冲突 格式难调,体面就不放了. 分析: julao们应该都看得出来就是个$LCT$板子,战争就$cut$,结束就$link$,询问就$find$.没了... 太久没打$LCT$,然后发 ...
 - 洛谷 P2486 [SDOI2011]染色 LCT
		
Code: #include <cstdio> //SDOI2010 染色 #include <algorithm> #include <cstring> #inc ...
 - 洛谷3348 大森林 (LCT + 虚点 + 树上差分)
		
这可真是道神仙题QWQ问了好多\(dalao\)才稍微明白了一丢丢做法 首先,我们假设不存在\(1\)操作,那么对于询问的一段区间中的所有的树,他们的形态应该是一样的 甚至可以直接理解为\(0\)操作 ...
 - 洛谷P1196 银河英雄传说[带权并查集]
		
题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山 ...
 - 洛谷4299首都(LCT维护动态重心+子树信息)
		
这个题目很有意思 QWQ 根据题目描述,我们可以知道,首都就是所谓的树的重心,那么我们假设每颗树的重心都是\(root\)的话,对于每次询问,我们只需要\(findroot(x)\)就可以. 那么如何 ...
 - 洛谷P1501 [国家集训队]Tree II(LCT,Splay)
		
洛谷题目传送门 关于LCT的其它问题可以参考一下我的LCT总结 一道LCT很好的练习放懒标记技巧的题目. 一开始看到又做加法又做乘法的时候我是有点mengbi的. 然后我想起了模板线段树2...... ...
 - 洛谷P3203 [HNOI2010]弹飞绵羊(LCT,Splay)
		
洛谷题目传送门 关于LCT的问题详见我的LCT总结 思路分析 首先分析一下题意.对于每个弹力装置,有且仅有一个位置可以弹到.把这样的一种关系可以视作边. 然后,每个装置一定会往后弹,这不就代表不存在环 ...
 - 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)
		
洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...
 - 洛谷U19464 山村游历(Wander)(LCT,Splay)
		
洛谷题目传送门 LCT维护子树信息常见套路详见我的总结 闲话 题目摘自WC模拟试题(by Philipsweng),原题目名Wander,"山村游历"是自己搞出来的中文名. 数据自 ...
 
随机推荐
- TCP/IP以及Socket聊天室带类库源码分享
			
TCP/IP以及Socket聊天室带类库源码分享 最近遇到个设备,需要去和客户的软件做一个网络通信交互,一般的我们的上位机都是作为客户端来和设备通信的,这次要作为服务端来监听客户端,在这个背景下,我查 ...
 - 手写 lodash/get、lodash/set 方法
			
动机:平时写js代码时经常遇到要使用 lodash 中 _.get 和 _.set 的情况,每次使用都要引用 lodash,总感觉很烦,能不能自己实现一个简单的方法来实现一样的功能呢? get 方法实 ...
 - Linux下sed找出IP中第四位
			
ip addr|sed -n '9p'|egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'|sed -nr 's#^.*inet (.*) b ...
 - Hounter
			
这题是概率与期望,不是很熟,所以冲了两篇题解才来写总结. 首先可以发现1猎人死的轮数是他之前死了的列人数加一. 那么题目转化为求先于一号猎人死的猎人数的期望值. 考虑这样一个事情,就是 ...
 - kernel_thread()和kthread_run()/kthread_create()的根本区别
			
0 本质区别 kthread_run()调用kthread_create(), kthread_create()加入链表后,有kthreadd()线程读取链表然后再调用kernel_thread()创 ...
 - JS020. Array map()函数查到需要的元素时跳出遍历循环,不再执行到数组边界
			
Array.prototype.map() map( ) 方法创建一个 新数组 *,其结果是该数组中的每个元素是调用一次提供的 函数后的返回值 *.[ MDN / RUNOOB ] * map 添加 ...
 - 手把手教你如何玩转消息中间件(ActiveMQ)
			
手把手教你如何玩转消息中间件(ActiveMQ) 2018年07月15日 18:07:39 Cs_hnu_scw 阅读数 12270 标签: 中间件消息中间件ActiveMQ分布式集群 更多 个人分类 ...
 - 使用Dockerfile Maven插件
			
我们常见开源项目中使用的Docker Maven插件是com.spotify:docker-maven-plugin.可用版本信息见Github. 通过其介绍可知该插件已经不再推荐使用,取而代之的是c ...
 - JS预编译过程
			
GO和AO 变量的预编译 实例1 console.log(a); var a=1; console.log(a); 实际编译过程: 将a存入预编译对象中,赋值为undefined: 真正的赋值语句当程 ...
 - Php实现简易购物商城系统
			
实现功能: 1.系统功能模块包括: 1)登陆注册模块 包括验证码.找回密码.注册模块中要使用Ajax判断用户名是否已经存在,使用正则表达式判断电子邮件.手机号和用户密码的格式是否合法. 2)用户管理模 ...