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

但是线段树不能做插入;

后来才知道用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. Oracle删除重复数据的几种常用方法

    1.有可区分的主键,其他数据相同 select * from 表名 dl where dl.id not in (select min(d.id) from  表名 d group by 重复列) 2 ...

  2. nargin函数的用法

    nargin是用来判断输入变量个数的函数,这样就可以针对不同的情况执行不同的功能.通常可以用他来设定一些默认值,如下面的函数. 函数文件examp.m:function fout=charray(a, ...

  3. Nim游戏(组合游戏Combinatorial Games)

    http://baike.baidu.com/view/1101962.htm?fr=aladdin Nim游戏是博弈论中最经典的模型(之一),它又有着十分简单的规则和无比优美的结论 Nim游戏是组合 ...

  4. 记工作中的git遇到的问题

    看了 git 回退到某版本后,再在此版本上更新,无法push 操作前,我备份了修改了目录,准备建一个分支进行操作 我在本地revert了一次,commit到了远程仓库.然后上个版本的修改给恢复了... ...

  5. sharepoint 备份和还原site脚本

    <个人积累,转载请注明出处> Backup-SPSite "http://www.abc.com/sites/TestWorkflowCenter" -path C:\ ...

  6. 4 WPF学习---系统的学习XAML语法

    转载:http://blog.csdn.net/fwj380891124/article/details/8093001 1,XAML文档的树形结构: UI在用户眼里面是个平面结构.如下图所示,在用户 ...

  7. Java的内存泄漏_与C/C++对比(转载总结)

    原文网址:http://developer.51cto.com/art/201111/302465.htm Java内存泄露的理解与解决(1)   一般来说内存泄漏有两种情况.一种情况如在C/C++ ...

  8. OI中神奇的神器fillchar

    传说,Pascal中有一个函数——fillchar.这是高手们装*用的利器,也是大家的神器(大家好才是真的好). 神器介绍: 百度百科说:“Fillchar是Turbo/Borland Pascal的 ...

  9. (转)TCP注册端口号大全

    分类: 网络与安全 cisco-sccp 2000/tcp Cisco SCCPcisco-sccp 2000/udp Cisco SCCp# Dan Wing <dwing&cisco ...

  10. extern int a[] VS extern int *a

    array VS pointer 参考: 1.Extern using pointer instead of array array is not pointer 2.extern array que ...