zoj 3765
一道区间更新、查询的题;
但是线段树不能做插入;
后来才知道用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的更多相关文章
- ZOJ 3765 Lights (伸展树splay)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3765 Lights Time Limit: 8 Seconds ...
- ZOJ 3765 Lights (zju March I)伸展树Splay
ZJU 三月月赛题,当时见这个题目没辙,没学过splay,敲了个链表TLE了,所以回来好好学了下Splay,这道题目是伸展树的第二题,对于伸展树的各项操作有了更多的理解,这题不同于上一题的用指针表示整 ...
- ZOJ People Counting
第十三届浙江省大学生程序设计竞赛 I 题, 一道模拟题. ZOJ 3944http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=394 ...
- ZOJ 3686 A Simple Tree Problem
A Simple Tree Problem Time Limit: 3 Seconds Memory Limit: 65536 KB Given a rooted tree, each no ...
- ZOJ Problem Set - 1394 Polar Explorer
这道题目还是简单的,但是自己WA了好几次,总结下: 1.对输入的总结,加上上次ZOJ Problem Set - 1334 Basically Speaking ac代码及总结这道题目的总结 题目要求 ...
- ZOJ Problem Set - 1392 The Hardest Problem Ever
放了一个长长的暑假,可能是这辈子最后一个这么长的暑假了吧,呵呵...今天来实验室了,先找了zoj上面简单的题目练练手直接贴代码了,不解释,就是一道简单的密文转换问题: #include <std ...
- ZOJ Problem Set - 1049 I Think I Need a Houseboat
这道题目说白了是一道平面几何的数学问题,重在理解题目的意思: 题目说,弗雷德想买地盖房养老,但是土地每年会被密西西比河淹掉一部分,而且经调查是以半圆形的方式淹没的,每年淹没50平方英里,以初始水岸线为 ...
- ZOJ Problem Set - 1006 Do the Untwist
今天在ZOJ上做了道很简单的题目是关于加密解密问题的,此题的关键点就在于求余的逆运算: 比如假设都是正整数 A=(B-C)%D 则 B - C = D*n + A 其中 A < D 移项 B = ...
- ZOJ Problem Set - 1001 A + B Problem
ZOJ ACM题集,编译环境VC6.0 #include <stdio.h> int main() { int a,b; while(scanf("%d%d",& ...
随机推荐
- Struts2的工作流程
Struts2如何实现MVC Struts2的参数封装: Struts2的运行原理图:
- 【Fibonacci】BestCoder #28B Fibonacci
Fibonacci Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- JSON对象和string的相互转换
JSON.stringify(obj) 将JSON转为字符串. JSON.parse(string) 将字符串转为JSON格式.
- c# 委托与异步调用
背景:在winform UI中,有时需要对控件进行比较频繁的刷新,如进度条.picturebox显示视频等.如果在主线程进行这些刷新操作,操作还未完成就将执行下一次刷新,程序将发生错误:如果只是创建另 ...
- [MSDN] 使用 SharePoint 2013 中的 JavaScript 库代码完成基本操作
MSDN:http://msdn.microsoft.com/zh-cn/library/jj163201.aspx 了解如何编写代码以在 SharePoint 2013 中使用 JavaScript ...
- css扁平化博客学习总结(四)content代码实现
1.根据功能,把不同的部分写出来,方便扩展 <div class="content"><!-- 内容开始 --> <section class=&qu ...
- scala学习笔记:高阶函数
scala> def power(y:Double)=(x:Double)=>Math.pow(x,y) warning: there were 1 deprecation warning ...
- Spring引用测试
上下文 using System; using Spring.Core; using Spring.Aop; using System; using Spring.Core; using Spring ...
- OC_NSString
// // main.m // OC_NSString // // Created by qianfeng on 15/6/10. // Copyright (c) 2015年 qianfeng. A ...
- dubbo监控活跃线程数
telnet对应dubbo服务的ip+端口号 status -l 其中的active就是当前的活跃线程数 通过程序定时探测写入DB,再查询渲染出来就好了 监控报警,如果已经有监控平台,可以通过一定的规 ...