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

但是线段树不能做插入;

后来才知道用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. Struts2的工作流程

    Struts2如何实现MVC Struts2的参数封装: Struts2的运行原理图:

  2. 【Fibonacci】BestCoder #28B Fibonacci

    Fibonacci Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  3. JSON对象和string的相互转换

    JSON.stringify(obj) 将JSON转为字符串. JSON.parse(string) 将字符串转为JSON格式.

  4. c# 委托与异步调用

    背景:在winform UI中,有时需要对控件进行比较频繁的刷新,如进度条.picturebox显示视频等.如果在主线程进行这些刷新操作,操作还未完成就将执行下一次刷新,程序将发生错误:如果只是创建另 ...

  5. [MSDN] 使用 SharePoint 2013 中的 JavaScript 库代码完成基本操作

    MSDN:http://msdn.microsoft.com/zh-cn/library/jj163201.aspx 了解如何编写代码以在 SharePoint 2013 中使用 JavaScript ...

  6. css扁平化博客学习总结(四)content代码实现

    1.根据功能,把不同的部分写出来,方便扩展 <div class="content"><!-- 内容开始 --> <section class=&qu ...

  7. scala学习笔记:高阶函数

    scala> def power(y:Double)=(x:Double)=>Math.pow(x,y) warning: there were 1 deprecation warning ...

  8. Spring引用测试

    上下文 using System; using Spring.Core; using Spring.Aop; using System; using Spring.Core; using Spring ...

  9. OC_NSString

    // // main.m // OC_NSString // // Created by qianfeng on 15/6/10. // Copyright (c) 2015年 qianfeng. A ...

  10. dubbo监控活跃线程数

    telnet对应dubbo服务的ip+端口号 status -l 其中的active就是当前的活跃线程数 通过程序定时探测写入DB,再查询渲染出来就好了 监控报警,如果已经有监控平台,可以通过一定的规 ...