非常裸的一棵Splay树,需要询问的是区间gcd,但是区间上每个数分成了两种状态,做的时候分别存在val[2]的数组里就好。区间gcd的时候基本上不支持区间的操作了吧。。不然你一个区间里加一个数gcd都不知道怎么维护了,所以维护点的gcd是比较简单的,题目存在删除和增加,所以Splay树无误了。删除一个结点或区间的方法是先把它get出来,然后令root->ch[1]->ch[0]=null,记得每次操作完要提根。

  1. #pragma warning(disable:4996)
  2. #include<cstring>
  3. #include<string>
  4. #include<cstdio>
  5. #include<iostream>
  6. #define ll long long
  7. #define maxn 401000
  8. using namespace std;
  9.  
  10. int n, q;
  11.  
  12. int gcd(int a, int b)
  13. {
  14. while (a&&b) { a %= b; a ^= b; b ^= a; a ^= b; }
  15. return a + b;
  16. }
  17.  
  18. struct Node
  19. {
  20. Node *ch[2], *p;
  21. int size, val[2], gval[2];
  22. int status;
  23. Node(){
  24. size = 0; val[0] = val[1] = 0; status = 0; gval[0] = gval[1] = 0;
  25. }
  26. bool d() {
  27. return this == p->ch[1];
  28. }
  29. void setc(Node *c, int d){
  30. ch[d] = c; c->p = this;
  31. }
  32. void cvalIt(int cval){
  33. val[status] = cval;
  34. gval[status] = gcd(val[status],gcd(ch[0]->gval[status], ch[1]->gval[status]));
  35. }
  36. void cstaIt(){
  37. swap(val[status ^ 1], val[status]);
  38. gval[status] = gcd(ch[0]->gval[status], ch[1]->gval[status]);
  39. gval[status ^ 1] = gcd(gval[status ^ 1], gcd(ch[0]->gval[status ^ 1], ch[1]->gval[status ^ 1]));
  40. status ^= 1;
  41. }
  42. void upd(){
  43. size = ch[0]->size + ch[1]->size + 1;
  44. for (int i = 0; i < 2; i++){
  45. gval[i] = gcd(gcd(ch[0]->gval[i], ch[1]->gval[i]), val[i]);
  46. }
  47. }
  48. }Tnull,*null=&Tnull;
  49.  
  50. Node mem[maxn], *C = mem;
  51.  
  52. Node*make(int v, int sta){
  53. C->ch[0] = C->ch[1] = null;
  54. C->size = 1;
  55. C->val[sta] = v; C->val[sta ^ 1] = 0;
  56. C->gval[sta] = v; C->gval[sta ^ 1] = 0;
  57. C->status = sta;
  58. return C++;
  59. }
  60.  
  61. int ax[maxn], bx[maxn];
  62.  
  63. Node*build(int l, int r)
  64. {
  65. if (l >= r) return null;
  66. int m = (l + r) >> 1;
  67. Node *t = make(ax[m], bx[m]);
  68. t->setc(build(l, m), 0);
  69. t->setc(build(m + 1, r), 1);
  70. t->upd();
  71. return t;
  72. }
  73.  
  74. Node *root;
  75. void rot(Node*t) {
  76. Node*p = t->p;
  77. //p->relax();
  78. //t->relax();
  79. int d = t->d();
  80. p->p->setc(t, p->d());
  81. p->setc(t->ch[!d], d);
  82. t->setc(p, !d);
  83. p->upd();
  84. if (p == root)
  85. root = t;
  86. }
  87.  
  88. void splay(Node*t, Node*f = null) {
  89. while (t->p != f) {
  90. if (t->p->p == f)
  91. rot(t);
  92. else
  93. t->d() == t->p->d() ? (rot(t->p), rot(t)) : (rot(t), rot(t));
  94. }
  95. t->upd();
  96. }
  97.  
  98. Node* select(int k) {
  99. for (Node*t = root;;) {
  100. //t->relax();
  101. int c = t->ch[0]->size;
  102. if (k == c)
  103. return t;
  104. if (k > c)
  105. k -= c + 1, t = t->ch[1];
  106. else
  107. t = t->ch[0];
  108. }
  109. }
  110.  
  111. Node*&get(int l, int r) { //[l,r)
  112. Node*L = select(l - 1);
  113. Node*R = select(r);
  114. splay(L);
  115. splay(R, L);
  116. return R->ch[0];
  117. }
  118.  
  119. void print(Node* x)
  120. {
  121. if (x == null) return;
  122. print(x->ch[0]);
  123. printf(" %d", x->val[0]);
  124. print(x->ch[1]);
  125. }
  126.  
  127. int main()
  128. {
  129. while (~scanf("%d%d", &n, &q))
  130. {
  131. for (int i = 1; i <= n; i++){
  132. scanf("%d%d", &ax[i], &bx[i]);
  133. }
  134. C = mem;
  135. ax[0] = ax[n + 1] = 0; bx[0] = bx[n + 1] = 0;
  136. root = build(0, n + 2); root->p = null;
  137. char type[3];
  138. int li, ri, si,vi;
  139. for (int i = 0; i < q; i++){
  140. scanf("%s", type);
  141. if (type[0] == 'Q'){
  142. scanf("%d%d%d", &li, &ri, &si);
  143. Node* &t=get(li, ri+1);
  144. if (t->gval[si]) {
  145. printf("%d\n", t->gval[si]);
  146. }
  147. else puts("-1");
  148. }
  149. else if (type[0] == 'I'){
  150. scanf("%d%d%d", &li, &vi, &si);
  151. Node *&t = get(li, li + 1);
  152. t->ch[1] = make(vi, si);
  153. splay(t);
  154. }
  155. else if (type[0] == 'D' ){
  156. scanf("%d", &li);
  157. Node *&t = get(li, li+1);
  158. root->ch[1]->ch[0] = null;
  159. splay(root->ch[1]);
  160. }
  161. else if (type[0] == 'R'){
  162. scanf("%d", &li);
  163. Node *&t = get(li, li + 1);
  164. t->cstaIt();
  165. splay(t);
  166. }
  167. else if (type[0] == 'M'){
  168. scanf("%d%d", &li, &vi);
  169. Node *&t = get(li, li + 1);
  170. t->cvalIt(vi);
  171. splay(t);
  172. }
  173. }
  174. }
  175. return 0;
  176. }

ZOJ3765 Lights Splay树的更多相关文章

  1. Splay树-Codevs 1296 营业额统计

    Codevs 1296 营业额统计 题目描述 Description Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司 ...

  2. Splay树再学习

    队友最近可能在学Splay,然后让我敲下HDU1754的题,其实是很裸的一个线段树,不过用下Splay也无妨,他说他双旋超时,单旋过了,所以我就敲来看下.但是之前写的那个Splay越发的觉得不能看,所 ...

  3. 暑假学习日记:Splay树

    从昨天开始我就想学这个伸展树了,今天花了一个上午2个多小时加下午2个多小时,学习了一下伸展树(Splay树),学习的时候主要是看别人博客啦~发现下面这个博客挺不错的http://zakir.is-pr ...

  4. 1439. Battle with You-Know-Who(splay树)

    1439 路漫漫其修远兮~ 手抄一枚splay树 长长的模版.. 关于spaly树的讲解   网上很多随手贴一篇 貌似这题可以用什么bst啦 堆啦 平衡树啦 等等 这些本质都是有共同点的 查找.删除特 ...

  5. 伸展树(Splay树)的简要操作

    伸展树(splay树),是二叉排序树的一种.[两个月之前写过,今天突然想写个博客...] 伸展树和一般的二叉排序树不同的是,在每次执行完插入.查询.删除等操作后,都会自动平衡这棵树.(说是自动,也就是 ...

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

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

  7. hdu 3436 splay树+离散化*

    Queue-jumpers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  8. hdu 1890 splay树

    Robotic Sort Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  9. hdu3487 splay树

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

随机推荐

  1. 在Windows Phone中使用HTML编程

    在开发Windows Phone的项目中,需求中有几个页面是要用表格来布局的(效果图如下),由于Grid中有的边线是虚的,而且没有边线,果断放弃了,用了border将表格的线加上去了.于是在有表格布局 ...

  2. ISE 中使用system generate

    本文讲解简单的ISE中使用system generate,system generate基本使用规则在此不详细说明可以见博客http://blog.csdn.net/xiabodan/article/ ...

  3. ADO.NET笔记——利用Command对象的ExecuteScalar()方法返回一个数据值

    相关知识: 有些SQL操作,例如SUM,只会从数据库返回一个数据值,而不是多行数据 尽管也可以使用ExecuteReader()返回一个DataReader对象,代表该数据值,但是使用Command对 ...

  4. WP开发笔记——页面传参

    WP APP页面与页面之间参数的传递可以通过程序的App类设置全局变量. 由于App 类继承自Application类,而通过Application的Current属性可以获取到与当前程序关联的App ...

  5. java.lang.NoClassDefFoundError Adding a jar to an RCP application

    给RCP中加入jar包与一般的java工程是有些个区别的,否则会出现"java.lang.NoClassDefFoundError" Open plug-in.xmlGo to R ...

  6. Android:自定义控件样式(Selector)

    前言 在开发一个应用程序过程中不可避免的要去修改组件的样式,比如按钮.输入框等.现在就看下如何通过Seletor实现样式的自定义.先看下简单的效果对比

  7. mysql主从备份、主从切换的例子

    指定binlog(因为时通过binlog实现数据同步的) 配置完后重启数据库服务,用show master status可以看到Master信息. StepB: 在SerB的my.cnf中指定 [ht ...

  8. linux查看硬件信息的命令(图文)

    发布:脚本学堂/Linux命令  编辑:JB02   2013-12-23 21:48:18  [大 中 小] 转自:http://www.jbxue.com/LINUXjishu/14996.htm ...

  9. Linux下iptables拦截Nginx的问题

    环境:CentOS 6.4 X64,Nginx 1.5.3 问题:配置好Nginx后,加入了“iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT” ...

  10. Linux&UNIX上卸载GoldenGate的方法

    1. Log on to the database server (as oracle) where the GoldenGate software is installed. [root@oracl ...