一道区间更新、查询的题;

但是线段树不能做插入;

后来才知道用splay;

splay用来做区间查询的话,先将l-1旋转到根节点,然后把r+1旋转到根节点的右节点;

这样的话,根节点的右节点的左子树就是我们要的区间;

我的代码是网上大神的代码改了一下过来的,存着做模板;

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 2000009
#define lch(rt) son[rt][0]
#define rch(rt) son[rt][1]
using namespace std; int son[maxn][],fa[maxn],size[maxn],val[maxn],st[maxn];
int gcd[maxn][],root,cnt;
int num[maxn*],fst[maxn*]; int get_gcd(int a,int b)
{
if(a==-)return b;
if(b==-)return a;
int c;
while(b)
{
c=a%b;
a=b;
b=c;
}
return a;
} void newnode(int &rt,int father,int v,int state)
{
rt=++cnt;
son[rt][]=son[rt][]=;
size[rt]=;
val[rt]=v;
fa[rt]=father;
gcd[rt][state]=v,gcd[rt][state^]=-;//attention;
st[rt]=state;
} void maintain(int rt)
{
size[rt]=size[son[rt][]]+size[son[rt][]]+;
gcd[rt][]=get_gcd(gcd[lch(rt)][],gcd[rch(rt)][]);
gcd[rt][]=get_gcd(gcd[lch(rt)][],gcd[rch(rt)][]);
gcd[rt][st[rt]]=get_gcd(gcd[rt][st[rt]],val[rt]);
} void rotate(int x,int kind)
{
int y=fa[x];
son[y][kind^]=son[x][kind];
fa[son[x][kind]]=y;
if(fa[y])
son[fa[y]][son[fa[y]][]==y]=x;
fa[x]=fa[y];
son[x][kind]=y;
fa[y]=x;
maintain(y);
} void splay(int rt,int goal)
{
while(fa[rt]!=goal)
{
int y=fa[rt];
if(fa[y]==goal)
rotate(rt,son[y][]==rt);
else
{
int kind=son[fa[y]][]==y;
if(son[y][kind]==rt)
{
rotate(rt,kind^);
rotate(rt,kind);
}
else
{
rotate(y,kind);
rotate(rt,kind);
}
}
}
maintain(rt);
if(goal==) root=rt;
} void rotateto(int k,int goal)//把第k个点旋转到目标位置;
{
int rt=root;
while(size[lch(rt)]!=k)
{
if(size[lch(rt)]>k)
rt=lch(rt);
else
{
k-=(size[lch(rt)]+);
rt=rch(rt);
}
}
splay(rt,goal);
} void build(int l,int r,int &rt,int father)
{
if(l>r) return ;
int m=(l+r)>>;
newnode(rt,father,num[m],fst[m]);
build(l,m-,lch(rt),rt);
build(m+,r,rch(rt),rt);
maintain(rt);
} int query(int L,int R,int state)
{
rotateto(L-,);
rotateto(R+,root);
return gcd[lch(rch(root))][state];
} void insert(int pos,int v,int state)//前端插入
{
rotateto(pos,);
if(lch(root)==)
{
newnode(lch(root),root,v,state);
maintain(root);
return ;
}
int rc=lch(root);
while(rch(rc))
rc=rch(rc);
splay(rc,root);
newnode(rch(rc),rc,v,state);
maintain(rc);
maintain(root);
} void del(int pos)
{
rotateto(pos,);
if(lch(root)==)
{
root=rch(root);
fa[root]=;
return ;
}
int rc=lch(root);
while(rch(rc)) rc=rch(rc);
splay(rc,root);
int rt=rch(root);
rch(rc)=rt;
fa[rt]=rc;
root=rc;
fa[rc]=;
maintain(root);
} void changes(int pos)
{
rotateto(pos,);
st[root]^=;
maintain(root);
} void modify(int pos,int v)
{
rotateto(pos,);
val[root]=v;
maintain(root);
} void init(int n)
{
for(int i=;i<n;++i)
scanf("%d%d",&num[i],&fst[i]);
lch()=rch()=;
fa[]=size[]=;val[]=-;
gcd[][]=gcd[][]=-;
cnt=;
newnode(root,,-,);
newnode(rch(root),root,-,);
build(,n-,lch(rch(root)),rch(root));
maintain(rch(root));
maintain(root);
} char s[];
int l,r,pos,state,v; int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
init(n);
while(m--)
{
scanf("%s",s);
if(s[]=='Q')
{
scanf("%d%d%d",&l,&r,&state);
int ans=query(l,r,state);
printf("%d\n",ans);
}
else if(s[]=='I')
{
scanf("%d%d%d",&pos,&v,&state);
insert(pos+,v,state);
}
else if(s[]=='D')
{
scanf("%d",&pos);
del(pos);
}
else if(s[]=='R')
{
scanf("%d",&pos);
changes(pos);
}
else
{
scanf("%d%d",&pos,&v);
modify(pos,v);
}
}
}
return ;
}

zoj 3765的更多相关文章

  1. ZOJ 3765 Lights (伸展树splay)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3765 Lights Time Limit: 8 Seconds ...

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

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

  3. ZOJ People Counting

    第十三届浙江省大学生程序设计竞赛 I 题, 一道模拟题. ZOJ  3944http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=394 ...

  4. ZOJ 3686 A Simple Tree Problem

    A Simple Tree Problem Time Limit: 3 Seconds      Memory Limit: 65536 KB Given a rooted tree, each no ...

  5. ZOJ Problem Set - 1394 Polar Explorer

    这道题目还是简单的,但是自己WA了好几次,总结下: 1.对输入的总结,加上上次ZOJ Problem Set - 1334 Basically Speaking ac代码及总结这道题目的总结 题目要求 ...

  6. ZOJ Problem Set - 1392 The Hardest Problem Ever

    放了一个长长的暑假,可能是这辈子最后一个这么长的暑假了吧,呵呵...今天来实验室了,先找了zoj上面简单的题目练练手直接贴代码了,不解释,就是一道简单的密文转换问题: #include <std ...

  7. ZOJ Problem Set - 1049 I Think I Need a Houseboat

    这道题目说白了是一道平面几何的数学问题,重在理解题目的意思: 题目说,弗雷德想买地盖房养老,但是土地每年会被密西西比河淹掉一部分,而且经调查是以半圆形的方式淹没的,每年淹没50平方英里,以初始水岸线为 ...

  8. ZOJ Problem Set - 1006 Do the Untwist

    今天在ZOJ上做了道很简单的题目是关于加密解密问题的,此题的关键点就在于求余的逆运算: 比如假设都是正整数 A=(B-C)%D 则 B - C = D*n + A 其中 A < D 移项 B = ...

  9. ZOJ Problem Set - 1001 A + B Problem

    ZOJ ACM题集,编译环境VC6.0 #include <stdio.h> int main() { int a,b; while(scanf("%d%d",& ...

随机推荐

  1. 2013 ACM/ICPC 长沙现场赛 A题 - Alice's Print Service (ZOJ 3726)

    Alice's Print Service Time Limit: 2 Seconds      Memory Limit: 65536 KB Alice is providing print ser ...

  2. [转载][记录]javascript生成不重复的随机数

    参考链接:javascript生成不重复的随机数 项目播放视频,是无序的,有上下两个按钮,所以需要生成1,8不重复的随机数数组,如: ,,,,,,, 然后再split一次,就是数组了. 拿来主义了

  3. ZooKeeper(3.4.5) - 使用 Curator(2.7.0) 监听事件

    ZooKeeper原生的API支持通过注册Watcher来进行事件监听,但是Watcher通知是一次性的,因此开发过程中需要反复注册Watcher,比较繁琐.Curator引入了Cache来监听Zoo ...

  4. scala学习笔记:理解stream和view

    先来个正常的: scala> (0 to 5).map((x:Int)=>{println(x);x*2}).foreach(println) 0 1 2 3 4 5 0 2 4 6 8 ...

  5. GestureDetector类及其用法

    转载子:http://www.cnblogs.com/rayray/p/3422734.html 项目中有需求:针对一个imageview,点击需要查看大图,左右滑动能执行翻页. 自己对手势这一块并不 ...

  6. 修改arcgis server默认js和css连接地址

    当使用ArcGIS Server 10.1发布了一个地图服务之后,在ArcGIS Server 10.1的机器上使用浏览器进入http://localhost:6080/arcgis/rest/ser ...

  7. ### 学习《C++ Primer》- 6

    Part 6: 拷贝控制(第13章) // @author: gr // @date: 2015-01-08 // @email: forgerui@gmail.com 一.拷贝.赋值与销毁 拷贝构造 ...

  8. [GeekBand] C++学习笔记(1)——以复数类为例

    本篇笔记以复数类(不含指针的类)为例进行面向对象的学习 ========================================================= 复数类的声明: class ...

  9. POJ 2127 Greatest Common Increasing Subsequence -- 动态规划

    题目地址:http://poj.org/problem?id=2127 Description You are given two sequences of integer numbers. Writ ...

  10. Linux DNS 设置失败

    在执行 yum install gcc 时 发现下载失败 ping www.baidu.com ping 不通 ping 百度的IP:220.181.111.188却能ping 通 由此证明是DNS的 ...