当前位置: 首页 > news >正文

ZOJ3765 Lights Splay树

非常裸的一棵Splay树,需要询问的是区间gcd,但是区间上每个数分成了两种状态,做的时候分别存在val[2]的数组里就好。区间gcd的时候基本上不支持区间的操作了吧。。不然你一个区间里加一个数gcd都不知道怎么维护了,所以维护点的gcd是比较简单的,题目存在删除和增加,所以Splay树无误了。删除一个结点或区间的方法是先把它get出来,然后令root->ch[1]->ch[0]=null,记得每次操作完要提根。

#pragma warning(disable:4996)
#include<cstring>
#include<string>
#include<cstdio>
#include<iostream>
#define ll long long
#define maxn 401000
using namespace std;

int n, q;

int gcd(int a, int b)
{
	while (a&&b) { a %= b; a ^= b; b ^= a; a ^= b; }
	return a + b;
}

struct Node
{
	Node *ch[2], *p;
	int size, val[2], gval[2];
	int status;
	Node(){
		size = 0; val[0] = val[1] = 0; status = 0; gval[0] = gval[1] = 0;
	}
	bool d() {
		return this == p->ch[1];
	}
	void setc(Node *c, int d){
		ch[d] = c; c->p = this;
	}
	void cvalIt(int cval){
		val[status] = cval;
		gval[status] = gcd(val[status],gcd(ch[0]->gval[status], ch[1]->gval[status]));
	}
	void cstaIt(){
		swap(val[status ^ 1], val[status]);
		gval[status] = gcd(ch[0]->gval[status], ch[1]->gval[status]);
		gval[status ^ 1] = gcd(gval[status ^ 1], gcd(ch[0]->gval[status ^ 1], ch[1]->gval[status ^ 1]));
		status ^= 1;
	}
	void upd(){
		size = ch[0]->size + ch[1]->size + 1;
		for (int i = 0; i < 2; i++){
			gval[i] = gcd(gcd(ch[0]->gval[i], ch[1]->gval[i]), val[i]);
		}
	}
}Tnull,*null=&Tnull;

Node mem[maxn], *C = mem;

Node*make(int v, int sta){
	C->ch[0] = C->ch[1] = null;
	C->size = 1;
	C->val[sta] = v; C->val[sta ^ 1] = 0;
	C->gval[sta] = v; C->gval[sta ^ 1] = 0;
	C->status = sta;
	return C++;
}

int ax[maxn], bx[maxn];

Node*build(int l, int r)
{
	if (l >= r) return null;
	int m = (l + r) >> 1;
	Node *t = make(ax[m], bx[m]);
	t->setc(build(l, m), 0);
	t->setc(build(m + 1, r), 1);
	t->upd();
	return t;
}

Node *root;
void rot(Node*t) {
	Node*p = t->p;
	//p->relax();
	//t->relax();
	int d = t->d();
	p->p->setc(t, p->d());
	p->setc(t->ch[!d], d);
	t->setc(p, !d);
	p->upd();
	if (p == root)
		root = t;
}

void splay(Node*t, Node*f = null) {
	while (t->p != f) {
		if (t->p->p == f)
			rot(t);
		else
			t->d() == t->p->d() ? (rot(t->p), rot(t)) : (rot(t), rot(t));
	}
	t->upd();
}

Node* select(int k) {
	for (Node*t = root;;) {
		//t->relax();
		int c = t->ch[0]->size;
		if (k == c)
			return t;
		if (k > c)
			k -= c + 1, t = t->ch[1];
		else
			t = t->ch[0];
	}
}

Node*&get(int l, int r) { //[l,r)
	Node*L = select(l - 1);
	Node*R = select(r);
	splay(L);
	splay(R, L);
	return R->ch[0];
}

void print(Node* x)
{
	if (x == null) return;
	print(x->ch[0]);
	printf(" %d", x->val[0]);
	print(x->ch[1]);
}





int main()
{
	while (~scanf("%d%d", &n, &q))
	{
		for (int i = 1; i <= n; i++){
			scanf("%d%d", &ax[i], &bx[i]);
		}
		C = mem;
		ax[0] = ax[n + 1] = 0; bx[0] = bx[n + 1] = 0;
		root = build(0, n + 2); root->p = null;
		char type[3];
		int li, ri, si,vi;
		for (int i = 0; i < q; i++){
			scanf("%s", type);
			if (type[0] == 'Q'){
				scanf("%d%d%d", &li, &ri, &si);
				Node* &t=get(li, ri+1);
				if (t->gval[si]) {
					printf("%d\n", t->gval[si]);
				}
				else puts("-1");
			}
			else if (type[0] == 'I'){
				scanf("%d%d%d", &li, &vi, &si);
				Node *&t = get(li, li + 1);
				t->ch[1] = make(vi, si);
				splay(t);
			}
			else if (type[0] == 'D' ){
				scanf("%d", &li);
				Node *&t = get(li, li+1);
				root->ch[1]->ch[0] = null;
				splay(root->ch[1]);
			}
			else if (type[0] == 'R'){
				scanf("%d", &li);
				Node *&t = get(li, li + 1);
				t->cstaIt();
				splay(t);
			}
			else if (type[0] == 'M'){
				scanf("%d%d", &li, &vi);
				Node *&t = get(li, li + 1);
				t->cvalIt(vi);
				splay(t);
			}
		}
	}
	return 0;
}

 

转载于:https://www.cnblogs.com/chanme/p/3578978.html

相关文章:

  • 4个实用的微服务测试策略
  • float,double和decimal类型
  • iOS:高仿闲鱼、京东等列表底部分页视图
  • 使用MDI 和 XtraTabbedMdiManager 后 选项卡切换后Ribbon 合并后不选中MDI子窗...
  • java~springboot~ibatis Invalid bound statement (not found)原因
  • c#正则表达式
  • 解码 | 25 分钟开发分布式架构的转账小程序
  • 删除2018年以前的文件
  • UTF-8编码规则
  • Java 实现阿里云短信
  • Slog80_打包ArthurSlogMarkdownEditor编辑器至mac平台dmg安装包GET!
  • 一个网站同时监听两个端口
  • DataSet数据转换string字符串
  • Android 各种路径详细说明
  • 【SQL Server DBA】日常巡检1:数据库空间、状态、使用的监控
  • 分享一款快速APP功能测试工具
  • Linux下的乱码问题
  • socket.io+express实现聊天室的思考(三)
  • SQLServer插入数据
  • TypeScript实现数据结构(一)栈,队列,链表
  • windows下mongoDB的环境配置
  • 给Prometheus造假数据的方法
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 以太坊客户端Geth命令参数详解
  • 原生JS动态加载JS、CSS文件及代码脚本
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • ![CDATA[ ]] 是什么东东
  • ${ }的特别功能
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (2)(2.10) LTM telemetry
  • (9)目标检测_SSD的原理
  • (libusb) usb口自动刷新
  • (定时器/计数器)中断系统(详解与使用)
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • .NET Core 2.1路线图
  • .NET 使用配置文件
  • .NET 应用启用与禁用自动生成绑定重定向 (bindingRedirect),解决不同版本 dll 的依赖问题
  • .Net程序帮助文档制作
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .net专家(张羿专栏)
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • [1] 平面(Plane)图形的生成算法
  • [2013AAA]On a fractional nonlinear hyperbolic equation arising from relative theory
  • [G-CS-MR.PS02] 機巧之形2: Ruler Circle
  • [hdu 2826] The troubles of lmy [简单计算几何 - 相似]
  • [HNOI2008]Cards
  • [LeetCode] 196. 删除重复的电子邮箱
  • [Linux](15)线程基础,线程控制,线程的互斥与同步
  • [LLM]大模型八股知识点(一)
  • [New Portal]Windows Azure Virtual Machine (3) 在VM上挂载磁盘