题目链接

附纯SplayTLE代码及主要思路:

  1. /*
  2. 可以看做序列有n段,Insert是每次在每一段最后插入一个元素
  3. 只有插入,没有删除,所以插入一个元素对于询问1影响的只有该元素与前边一个元素(同段)、下一段的开头元素
  4. 故只需删掉该段最后元素与下一段开头元素的差,再加入新元素与下一段开头的差即可 -> 记录差值
  5. 对于询问2,将值在平衡树中插入,能有影响的就是相邻两个值了(最小值只可能从中产生) -> 记录值
  6. 所以对于每一段只需记录开头与结尾元素,剩下的就是插入删除了
  7. 询问2中相邻两个值是前驱后继!不能直接用子节点!
  8. */
  9. #include<cstdio>
  10. #include<cctype>
  11. #include<algorithm>
  12. const int N=5e5+5,M=N*3;
  13. int n,q,st[N],ed[N],Min2=1e9;
  14. struct Splay_Tree
  15. {
  16. int size,root,son[M][2],fa[M],sz[M],cnt[M],t[M];
  17. inline void Update(int rt)
  18. {
  19. sz[rt]=sz[son[rt][0]]+sz[son[rt][1]]+cnt[rt];
  20. }
  21. void Rotate(int x,int &k)
  22. {
  23. int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
  24. if(a==k) k=x;
  25. else son[b][son[b][1]==a]=x;
  26. fa[x]=b, fa[a]=x, fa[son[x][r]]=a;
  27. son[a][l]=son[x][r], son[x][r]=a;
  28. Update(a), Update(x);
  29. }
  30. void Splay(int x,int &k)
  31. {
  32. while(x!=k)
  33. {
  34. int a=fa[x],b=fa[a];
  35. if(a!=k) (son[a][1]==x^son[b][1]==a)?Rotate(x,k):Rotate(a,k);
  36. Rotate(x,k);
  37. }
  38. }
  39. void Update_Min2(int k,int w)
  40. {
  41. while(son[k][w]) k=son[k][w];
  42. Min2=std::min(Min2,std::abs(t[root]-t[k]));
  43. }
  44. void Insert(int v,int k,bool opt)
  45. {
  46. int f=0;
  47. while(t[k]!=v && k) f=k,k=son[k][v>t[k]];
  48. if(k) ++cnt[k],++sz[k];
  49. else
  50. {
  51. k=++size, sz[k]=cnt[k]=1, t[k]=v, fa[k]=f;
  52. if(f) son[f][v>t[f]]=k;
  53. }
  54. Splay(k,root);
  55. if(!(opt*Min2)) return;
  56. if(cnt[k]>1) Min2=0;
  57. if(son[k][0]) Update_Min2(son[k][0],1);
  58. if(son[k][1]) Update_Min2(son[k][1],0);
  59. }
  60. void Get_Rank(int v,int k)
  61. {
  62. while(t[k]!=v) k=son[k][v>t[k]];
  63. Splay(k,root);
  64. }
  65. void Delete(int v)
  66. {
  67. Get_Rank(v,root);
  68. int k=root;
  69. if(cnt[k]>1) --sz[k],--cnt[k];
  70. else if(son[k][0]*son[k][1])
  71. {
  72. int p=son[k][0];root=k=son[k][1];
  73. while(son[k][0]) k=son[k][0];
  74. fa[p]=k, son[k][0]=p, sz[k]+=sz[p];
  75. Splay(k,root);
  76. }
  77. else root=son[k][0]|son[k][1];
  78. fa[root]=0;
  79. }
  80. int Query_Min()
  81. {
  82. int k=root;
  83. while(son[k][0]) k=son[k][0];
  84. return t[k];
  85. }
  86. }t1,t2;
  87. inline int read()
  88. {
  89. int now=0,f=1;register char c=getchar();
  90. for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
  91. for(;isdigit(c);now=now*10+c-'0',c=getchar());
  92. return now*f;
  93. }
  94. void Ins()
  95. {
  96. int p=read(),v=read();
  97. if(p!=n)
  98. t1.Delete(std::abs(st[p+1]-ed[p])),
  99. t1.Insert(std::abs(st[p+1]-v),t1.root,0);
  100. t1.Insert(std::abs(ed[p]-v),t1.root,0);
  101. ed[p]=v;
  102. if(Min2) t2.Insert(v,t2.root,1);
  103. }
  104. int main()
  105. {
  106. #ifndef ONLINE_JUDGE
  107. freopen("1110.in","r",stdin);
  108. #endif
  109. n=read(),q=read();
  110. st[1]=ed[1]=read(),t2.Insert(st[1],t2.root,1);
  111. for(int i=2;i<=n;++i)
  112. st[i]=ed[i]=read(),t1.Insert(std::abs(st[i]-st[i-1]),t1.root,0),t2.Insert(st[i],t2.root,1);
  113. char s[20];int p,v;
  114. while(q--)
  115. {
  116. scanf("%s",s);
  117. if(s[0]=='I') Ins();
  118. else if(s[4]=='G') printf("%d\n",t1.Query_Min());
  119. else printf("%d\n",Min2);
  120. }
  121. return 0;
  122. }

AC:

  1. /*
  2. 对于询问1,直接用带修改的堆维护即可,能不用Splay就不用了
  3. 对于堆的修改,可以将要修改的元素另插入一个堆,当两个堆的堆顶相等时,就都弹出
  4. 对于询问2,需要前驱后继,还是用平衡树
  5. 询问2中相邻两个值是前驱后继!不能直接用子节点!
  6. */
  7. #include<cstdio>
  8. #include<cctype>
  9. #include<algorithm>
  10. const int N=5e5+5,M=N*3;
  11. int n,q,st[N],ed[N],Min2=1e9;
  12. struct Splay_Tree
  13. {
  14. int size,root,son[M][2],fa[M],sz[M],cnt[M],t[M];
  15. inline void Update(int rt)
  16. {
  17. sz[rt]=sz[son[rt][0]]+sz[son[rt][1]]+cnt[rt];
  18. }
  19. void Rotate(int x,int &k)
  20. {
  21. int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
  22. if(a==k) k=x;
  23. else son[b][son[b][1]==a]=x;
  24. fa[x]=b, fa[a]=x, fa[son[x][r]]=a;
  25. son[a][l]=son[x][r], son[x][r]=a;
  26. Update(a), Update(x);
  27. }
  28. void Splay(int x,int &k)
  29. {
  30. while(x!=k)
  31. {
  32. int a=fa[x],b=fa[a];
  33. if(a!=k) (son[a][1]==x^son[b][1]==a)?Rotate(x,k):Rotate(a,k);
  34. Rotate(x,k);
  35. }
  36. }
  37. inline void Update_Min2(int k,int w)
  38. {
  39. while(son[k][w]) k=son[k][w];
  40. Min2=std::min(Min2,std::abs(t[root]-t[k]));
  41. }
  42. void Insert(int v,int k)
  43. {
  44. int f=0;
  45. while(t[k]!=v && k) f=k,k=son[k][v>t[k]];
  46. if(k) ++cnt[k],++sz[k];
  47. else
  48. {
  49. k=++size, sz[k]=cnt[k]=1, t[k]=v, fa[k]=f;
  50. if(f) son[f][v>t[f]]=k;
  51. }
  52. Splay(k,root);
  53. if(!Min2) return;
  54. if(cnt[k]>1) Min2=0;
  55. if(son[k][0]) Update_Min2(son[k][0],1);
  56. if(son[k][1]) Update_Min2(son[k][1],0);
  57. }
  58. }t;
  59. struct Heap
  60. {
  61. int sz,A[M];
  62. inline int Top()
  63. {
  64. return A[1];
  65. }
  66. void Push(int x)
  67. {
  68. A[++sz]=x;
  69. int now=sz,nxt=now>>1;
  70. while(now>1 && A[nxt]>A[now])
  71. std::swap(A[nxt],A[now]), now=nxt, nxt=now>>1;
  72. }
  73. void Pop()
  74. {
  75. A[1]=A[sz--];
  76. int now=1,nxt;
  77. while(now<<1<=sz)
  78. {
  79. nxt=now<<1;
  80. if(A[nxt]>A[nxt+1] && nxt<sz) ++nxt;
  81. if(A[nxt]>=A[now]) break;
  82. std::swap(A[now],A[nxt]);
  83. now=nxt;
  84. }
  85. }
  86. }h1,h2;
  87. inline int read()
  88. {
  89. int now=0,f=1;register char c=getchar();
  90. for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
  91. for(;isdigit(c);now=now*10+c-'0',c=getchar());
  92. return now*f;
  93. }
  94. void Ins()
  95. {
  96. int p=read(),v=read();
  97. if(p!=n)
  98. h2.Push(std::abs(st[p+1]-ed[p])),
  99. h1.Push(std::abs(st[p+1]-v));
  100. h1.Push(std::abs(ed[p]-v));
  101. ed[p]=v;
  102. if(Min2) t.Insert(v,t.root);
  103. }
  104. int Query_Min1()
  105. {
  106. while(h1.Top()==h2.Top()) h1.Pop(),h2.Pop();
  107. return h1.Top();
  108. }
  109. int main()
  110. {
  111. #ifndef ONLINE_JUDGE
  112. freopen("1110.in","r",stdin);
  113. #endif
  114. n=read(),q=read();
  115. st[1]=ed[1]=read(),t.Insert(st[1],t.root);
  116. for(int i=2;i<=n;++i)
  117. st[i]=ed[i]=read(),h1.Push(std::abs(st[i]-st[i-1])),t.Insert(st[i],t.root);
  118. char s[20];int p,v;
  119. while(q--)
  120. {
  121. scanf("%s",s);
  122. if(s[0]=='I') Ins();
  123. else if(s[4]=='G') printf("%d\n",Query_Min1());
  124. else printf("%d\n",Min2);
  125. }
  126. return 0;
  127. }

洛谷.1110.[ZJOI2007]报表统计(Splay Heap)的更多相关文章

  1. 洛谷.1110.[ZJOI2007]报表统计(Multiset Heap)

    题目链接 主要思路 /* 对于询问1,用堆代替multiset/Splay 对于询问2,multiset 1.注意哨兵元素 2.注意multiset中删除时是删除某元素的一个位置,而不是这个元素!这个 ...

  2. BZOJ1058或洛谷1110 [ZJOI2007]报表统计

    BZOJ原题链接 洛谷原题链接 STL 本题可以直接使用\(\mathtt{STL\ multiset}\)水过去. 因为本题插入数的操作实际上就是将原数列分为\(n\)段,在每一段的末尾插入数,所以 ...

  3. 洛谷.1110.[ZJOI2007]报表统计(Multiset)

    题目链接 主要思路 /* 其实只需要multiset即可 对于询问1,删除.插入差值,输出最小元素 对于询问2,插入后用前驱后继更新 1.注意哨兵元素 2.注意multiset中删除时是删除某元素的一 ...

  4. 洛谷 P1110 [ZJOI2007]报表统计 解题报告

    P1110 [ZJOI2007]报表统计 题目描述 \(Q\)的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小\(Q\)希望可以帮妈妈分担一些工作,作为她的生日礼物之一. 经过仔细 ...

  5. 2018.11.09 洛谷P1110 [ZJOI2007]报表统计(multiset)

    传送门 sb题. 直接用两个multisetmultisetmultiset维护相邻两个数的差值和所有数的前驱后继. 插入一个数的时候更新一下就行了. 代码: #include<bits/std ...

  6. BZOJ1058:[ZJOI2007]报表统计(Splay,堆)

    Description 小Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工 作,作为她的生日礼物之一.经过仔细观察,小Q发现统计一张报表实际上是维护一个 ...

  7. 洛谷P2234 [HNOI2002] 营业额统计 [splay]

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

  8. 洛谷.2234.[HNOI2002]营业额统计(Splay)

    题目链接 //模板吧 #include<cstdio> #include<cctype> #include<algorithm> using namespace s ...

  9. [ZJOI2007]报表统计(splay,堆)

    [ZJOI2007]报表统计(luogu) Description 题目描述 Q的妈妈是一个出纳,经常需要做一些统计报表的工作.今天是妈妈的生日,小Q希望可以帮妈妈分担一些工作,作为她的生日礼物之一. ...

随机推荐

  1. python3之redis

    1.redis简介 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(s ...

  2. ARM40-A5应用——fbset与液晶屏参数的适配【转】

    转自:https://blog.csdn.net/vonchn/article/details/80784579 ARM40-A5应用——fbset与液晶屏参数的适配 2018.6.18 版权声明:本 ...

  3. memcmp与strncmp函数【转】

    c中strncmp与memcmp的区别 函数:int memcmp (const void *a1, const void *a2, size_t size)        函数memcmp用于比较字 ...

  4. mysql caching_sha2_password异常分析

    使用navicat连接mysql报错 解决办法: 通过命令行登录mysql后,输入: alter user 'root'@'localhost' IDENTIFIED WITH mysql_nativ ...

  5. 整理一下odoo10在windows系统下部署的流程

    odoo10环境搭建 所需依赖: Python3.5 odoo10.0 Node.js PostgreSQL 9.5 PyCharm 专业版 1.首先先安装好Python3.5,并设置好环境变量 2. ...

  6. kerberos介绍

    重要术语 1. KDC 全称:key distributed center 作用:整个安全认证过程的票据生成管理服务,其中包含两个服务,AS和TGS 2. AS 全称:authentication s ...

  7. mysql语句判断是否存在记录,没有则插入新纪录否则不执行

    1 前言 由于项目需要,当某个表如果有记录,就不执行加入语句,否则加入新纪录(测试数据).思路是:判断表的记录是否为空,然后再决定是否插入 2 代码 DROP PROCEDURE IF EXISTS ...

  8. Android ImageView 的scaleType 属性图解

    ImageView 是 Android 中最常用的控件之一,而在使用ImageView时,必不可少的会使用到它的scaleType属性.该属性指定了你想让ImageView如何显示图片,包括是否进行缩 ...

  9. 在Vue中使用计时器笔记

    在Vue中使用了计时器,一定要记得在生命周期destroyed()里清掉,不然第二次进入这个组件,会出现很大的问题 destroyed () { // (很重要)当跳转到其他页面的时候,要在生命周期的 ...

  10. C#面向对象(继承的重载和构造函数)

    构造函数: 继承的重载: