题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3765

Lights


Time Limit: 8 Seconds      Memory Limit: 131072 KB

Now you have N lights in a line. Don't worry - the lights don't have color. The only status they have is on and off. And, each light has a value, too.

There is a boring student in ZJU. He decides to do some boring operations to the lights:

  1. L R status - Query the GCD (Greatest Common Divisor) of the value of the given status lights in range [LR]. For example, if now we have 3 lights which are {on, off and on}, and their value are {3, 5, 9}, then the GCD of the number of the lights on in [1, 3] is 3, and the lights off is 5.
  2. i value status - Add a light just behind to ith light. The initial status and the value is given also.
  3. i - Remove the ith light.
  4. i - If ith light is on, turn it off, else turn it on.
  5. i x - Modify the value of ith light to x.

Please help this boring guy to do this boring thing so that he can have time to find a girlfriend!

Input

The input contains multiple test cases. Notice there's no empty line between each test case.

For each test case, the first line of the a case contains two integers, N (1 ≤ N ≤ 200000) and Q (1 ≤ Q ≤ 100000), indicating the number of the lights at first and the number of the operations. In following N lines, each line contains two integers, Numi (1 ≤ Numi ≤ 1000000000) and Statusi (0 ≤ Statusi ≤ 1), indicating the number of the light i and the status of it. In following Q lines, each line indicating an operation, and the format is described above.

It is guaranteed that the range of the operations will be appropriate. For example, if there is only 10 lights, you will not receive an operation like "Q 1 11 0" or "D 11".

Output

For each Query operation, output an integer, which is the answer to the query. If no lights are with such status, please output -1.

Sample Input

3 12
27 1
32 0
9 1
Q 1 3 1
I 3 64 0
Q 2 4 0
Q 2 4 1
I 2 43 1
D 5
Q 1 2 1
M 1 35
Q 1 2 1
R 1
R 3
Q 1 2 1

Sample Output

9
32
9
27
35
-1

很裸的题目了,用splay维护也很简单,练练手而已。

 /* ***********************************************
Author :kuangbin
Created Time :2014/3/2 20:02:38
File Name :E:\2014ACM\比赛\ZOJ_March2014\I.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define Key_value ch[ch[root][1]][0]
const int MAXN = ;
int pre[MAXN],ch[MAXN][],key[MAXN],size[MAXN];
int root,tot1;
int sum0[MAXN],sum1[MAXN];//该子树对应状态的gcd
int st[MAXN]; //该节点的状态
int s[MAXN],tot2;//内存池和容量
//初始节点的值和状态
int a[MAXN];
int status[MAXN];
int n,q; long long gcd(long long a,long long b)
{
if(b == )return a;
else return gcd(b,a%b);
}
void NewNode(int &r,int father,int k,int _st)
{
if(tot2) r = s[tot2--];
else r = ++tot1;
pre[r] = father;
ch[r][] = ch[r][] = ;
key[r] = k;
st[r] = _st;
if(_st == ){sum0[r] = k; sum1[r] = ;}
else {sum1[r] = k; sum0[r] = ;}
size[r] = ;
}
void push_up(int r)
{
int lson = ch[r][], rson = ch[r][];
size[r] = size[lson] + size[rson] + ;
sum0[r] = sum1[r] = ;
sum0[r] = gcd(sum0[lson],sum0[rson]);
sum1[r] = gcd(sum1[lson],sum1[rson]);
if(st[r])sum1[r] = gcd(sum1[r],key[r]);
else sum0[r] = gcd(sum0[r],key[r]);
}
void push_down(int r)
{ }
void Build(int &x,int l,int r,int father)
{
if(l > r)return;
int mid = (l + r)/;
NewNode(x,father,a[mid],status[mid]);
Build(ch[x][],l,mid-,x);
Build(ch[x][],mid+,r,x);
push_up(x);
}
void Init()
{
root = tot1 = tot2 = ;
ch[root][] = ch[root][] = size[root] = pre[root] = ;
sum0[root] = sum1[root] = ;
NewNode(root,,,);
NewNode(ch[root][],root,,);
for(int i = ;i < n;i++)
scanf("%d%d",&a[i],&status[i]);
Build(Key_value,,n-,ch[root][]);
push_up(ch[root][]);
push_up(root);
}
void Rotate(int x,int kind)
{
int y = pre[x];
push_down(y);
push_down(x);
ch[y][!kind] = ch[x][kind];
pre[ch[x][kind]] = y;
if(pre[y])
ch[pre[y]][ch[pre[y]][]==y] = x;
pre[x] = pre[y];
ch[x][kind] = y;
pre[y] = x;
push_up(y);
}
void Splay(int r,int goal)
{
push_down(r);
while(pre[r] != goal)
{
if(pre[pre[r]] == goal)
{
Rotate(r,ch[pre[r]][] == r);
}
else
{
int y = pre[r];
int kind = ch[pre[y]][] == y;
if(ch[y][kind] == r)
{
Rotate(r,!kind);
Rotate(r,kind);
}
else
{
Rotate(y,kind);
Rotate(r,kind);
}
}
}
push_up(r);
if(goal == )root = r;
}
int Get_kth(int r,int k)
{
push_down(r);
int t = size[ch[r][]] + ;
if(t == k)return r;
if(t > k)return Get_kth(ch[r][],k);
else return Get_kth(ch[r][],k-t);
}
//在第pos个数后面插入一个数
void Insert(int pos,int _val,int _st)
{
Splay(Get_kth(root,pos+),);
Splay(Get_kth(root,pos+),root);
NewNode(Key_value,ch[root][],_val,_st);
push_up(ch[root][]);
push_up(root);
}
void erase(int r)
{
if(!r)return;
s[++tot2] = r;
erase(ch[r][]);
erase(ch[r][]);
}
//删除第pos个数
void Delete(int pos)
{
Splay(Get_kth(root,pos),);
Splay(Get_kth(root,pos+),root);
erase(Key_value);
pre[Key_value] = ;
Key_value = ;
push_up(ch[root][]);
push_up(root);
}
//改变第pos个数的状态
void Change(int pos)
{
Splay(Get_kth(root,pos),);
Splay(Get_kth(root,pos+),root);
st[Key_value] ^= ;
push_up(Key_value);
push_up(ch[root][]);
push_up(root);
}
//改变第pos个数的值
void Modify(int pos,int _val)
{
Splay(Get_kth(root,pos),);
Splay(Get_kth(root,pos+),root);
key[Key_value] = _val;
push_up(Key_value);
push_up(ch[root][]);
push_up(root); }
int Query(int L,int R,int _st)
{
int ans ;
Splay(Get_kth(root,L),);
Splay(Get_kth(root,R+),root);
if(_st == )ans = sum0[Key_value];
else ans = sum1[Key_value];
if(ans == )ans = -;
return ans;
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d%d",&n,&q) == )
{
Init();
char op[];
while(q--)
{
scanf("%s",op);
if(op[] == 'Q')
{
int L,R,_st;
scanf("%d%d%d",&L,&R,&_st);
printf("%d\n",Query(L,R,_st));
}
else if(op[] == 'I')
{
int pos,val,_st;
scanf("%d%d%d",&pos,&val,&_st);
Insert(pos,val,_st);
}
else if(op[] == 'D')
{
int pos;
scanf("%d",&pos);
Delete(pos);
}
else if(op[] == 'R')
{
int pos;
scanf("%d",&pos);
Change(pos);
}
else if(op[] == 'M')
{
int pos,val;
scanf("%d%d",&pos,&val);
Modify(pos,val);
}
}
}
return ;
}

ZOJ 3765 Lights (伸展树splay)的更多相关文章

  1. 树-伸展树(Splay Tree)

    伸展树概念 伸展树(Splay Tree)是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由Daniel Sleator和Robert Tarjan创造. (01) 伸展树属于二 ...

  2. 纸上谈兵: 伸展树 (splay tree)[转]

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢!  我们讨论过,树的搜索效率与树的深度有关.二叉搜索树的深度可能为n,这种情况下,每 ...

  3. K:伸展树(splay tree)

      伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(lgN)内完成插入.查找和删除操作.在伸展树上的一般操作都基于伸展操作:假设想要对一个二叉查找树执行一系列的查找操作,为了使 ...

  4. 高级搜索树-伸展树(Splay Tree)

    目录 局部性 双层伸展 查找操作 插入操作 删除操作 性能分析 完整源码 与AVL树一样,伸展树(Splay Tree)也是平衡二叉搜索树的一致,伸展树无需时刻都严格保持整棵树的平衡,也不需要对基本的 ...

  5. ZOJ 3765 Lights (zju March I)伸展树Splay

    ZJU 三月月赛题,当时见这个题目没辙,没学过splay,敲了个链表TLE了,所以回来好好学了下Splay,这道题目是伸展树的第二题,对于伸展树的各项操作有了更多的理解,这题不同于上一题的用指针表示整 ...

  6. 【BBST 之伸展树 (Splay Tree)】

    最近“hiho一下”出了平衡树专题,这周的Splay一直出现RE,应该删除操作指针没处理好,还没找出原因. 不过其他操作运行正常,尝试用它写了一道之前用set做的平衡树的题http://codefor ...

  7. [Splay伸展树]splay树入门级教程

    首先声明,本教程的对象是完全没有接触过splay的OIer,大牛请右上角.. 首先引入一下splay的概念,他的中文名是伸展树,意思差不多就是可以随意翻转的二叉树 PS:百度百科中伸展树读作:BoGa ...

  8. 伸展树Splay【非指针版】

    ·伸展树有以下基本操作(基于一道强大模板题:codevs维护队列): a[]读入的数组;id[]表示当前数组中的元素在树中节点的临时标号;fa[]当前节点的父节点的编号;c[][]类似于Trie,就是 ...

  9. 伸展树(Splay tree)的基本操作与应用

    伸展树的基本操作与应用 [伸展树的基本操作] 伸展树是二叉查找树的一种改进,与二叉查找树一样,伸展树也具有有序性.即伸展树中的每一个节点 x 都满足:该节点左子树中的每一个元素都小于 x,而其右子树中 ...

随机推荐

  1. Js表单验证控件

    演示地址:http://weishakeji.net/Utility/Verify/Index.htm    开源地址:https://github.com/weishakeji/Verify_Js ...

  2. 安装informatic过程中的错误

    1.Check if the DISPLAY variable is set export DISPLAY=192.168.3.201:0.0 在注销用户并切换到oracle或者infa 用户,就可以 ...

  3. 电容充放电时间常数RC计算方法

    进入正题前,我们先来回顾下电容的充放电时间计算公式,假设有电源Vu通过电阻R给电容C充电,V0为电容上的初始电压值,Vu为电容充满电后的电压值,Vt为任意时刻t时电容上的电压值,那么便可以得到如下的计 ...

  4. jquery.validate动态更改校验规则

    有时候表单中有多个字段是相互关联的,以下遇到的就是证件类型和证件号码的关联,在下拉框中选择不同的证件类型,证件号码的值的格式都是不同的,这就需要动态的改变校验规则. 点击(此处)折叠或打开 <! ...

  5. Java继承概述

    继承概述 : 父类(超类,基类): 子类(派生类): extends 只能继承一个类,Java不支持多重继承: 子类继承父类之后,子类可以调用父类的属性和方法, 也可以重写父类的属性和方法,还可以增加 ...

  6. laravel队列,事件简单使用方法

    A.队列的使用 1.队列配置文件存储在 config/queue.php 根据自己的情况进行配置 2..env文件 QUEUE_DRIVER=database(根据个人情况配置,redis等) 3.创 ...

  7. Linux学习笔记:常用命令grep、iconv、cp、mv、rm

    本篇记录一些近期常用的命令. 一.grep过滤 grep过滤 不包含某些字符串 cat test.txt | grep -v '.jpg' 过滤jpg结尾的图片 cat test.txt | grep ...

  8. mysql的完整卸载

    一.卸载MySQL数据库 1.检查mysql服务并关闭服务进程 (1)登录Linux后执行service mysqld status 或者service mysql status命令查看MySQL服务 ...

  9. **CI中自动类加载的用法总结

    总结: 哪一个类中用到某一个类,就在构造函数中加载这个类,比如m_attach,C_Feed类中有用到,那么就在构造函数中加载 控制器: class C_Feed extends CI_Control ...

  10. 【BZOJ】4128: Matrix

    题解 学习一下矩阵求逆 就是我们考虑这个矩阵 \(AA^{-1} = I\) 我们相当于让\(A\)乘上一个矩阵,变成\(I\) 我们可以利用初等行变换(只能应用初等行变换,或只应用初等列变换) 分三 ...