很有意思的题目,详细题解看这里 https://blog.csdn.net/qian99/article/details/38536559

自己的代码不知道哪里出了点问题

  1. /*
  2. rotate操作不会改变树的中序遍历结果,将初始的树按中序遍历结果拍扁在线段树上,
  3. 线段树结点维护每个结点的子树范围,自身权值和子树权值
  4. */
  5. #pragma comment(linker,"/STACK:102400000,102400000")
  6. #include<bits/stdc++.h>
  7. using namespace std;
  8. #define maxn 100005
  9. #define mod 1000000007
  10. #define ll long long
  11. int ch[maxn][],pre[maxn],n,m;
  12. int dfs_clock,lx[maxn],rx[maxn],w[maxn],id[maxn];//结点在线段树中的位置
  13. ll val[maxn];
  14. void dfs(int u){
  15. if(ch[u][]) dfs(ch[u][]);//先遍历左子树
  16. id[u]=++dfs_clock;val[dfs_clock]=w[u];//访问当前结点
  17. if(ch[u][]){
  18. lx[u]=lx[ch[u][]];//左边界
  19. val[id[u]]+=val[id[ch[u][]]];
  20. }
  21. else lx[u]=id[u];
  22.  
  23. if(ch[u][]) dfs(ch[u][]);//在访问右子树
  24. if(ch[u][]) {
  25. rx[u]=rx[ch[u][]];//右边界
  26. val[id[u]]+=val[id[ch[u][]]];
  27. }
  28. else rx[u]=id[u];
  29. val[id[u]]%=mod;
  30. }
  31. inline void getinv(int x){
  32. if(ch[x][]) lx[x]=lx[ch[x][]];
  33. else lx[x]=id[x];
  34. if(ch[x][]) rx[x]=rx[ch[x][]];
  35. else rx[x]=id[x];
  36. }
  37.  
  38. //线段树部分
  39. #define lson l,m,rt<<1
  40. #define rson m+1,r,rt<<1|1
  41. ll mul[maxn<<];
  42. inline void pushup(int rt){
  43. mul[rt]=mul[rt<<]*mul[rt<<|]%mod;
  44. }
  45. void build(int l,int r,int rt){
  46. if(l==r){mul[rt]=val[l];return;}
  47. int m=l+r>>;
  48. build(lson);
  49. build(rson);
  50. pushup(rt);
  51. }
  52. ll query(int L,int R,int l,int r,int rt){//查询区间[L,R]的乘积
  53. if(L<=l && R>=r) return mul[rt];
  54. int m=l+r>>;
  55. ll res=;
  56. if(L<=m) res=query(L,R,lson);
  57. if(R>m) res*=query(L,R,rson),res%=mod;
  58. return res;
  59. }
  60. void update(int pos,int l,int r,int rt,int val){
  61. if(l==r){mul[rt]=val;return;}
  62. int m=l+r>>;
  63. if(pos<=m) update(pos,lson,val);
  64. else update(pos,rson,val);
  65. pushup(rt);
  66. }
  67.  
  68. void rotate(int x,int kind){//右转是0,左转是1,和伸展树操作刚好相反。。
  69. int son=ch[x][kind];
  70. if(son==) return;
  71. ch[x][kind]=ch[son][kind^];
  72. if(ch[son][kind^]) pre[ch[son][kind^]]=x;
  73. if(pre[x]) ch[pre[x]][ch[pre[x]][]==x]=son;
  74. pre[son]=pre[x];
  75. ch[son][kind^]=x;
  76. pre[x]=son;
  77.  
  78. val[id[x]]=(w[x]+val[id[ch[x][]]]+val[id[ch[x][]]])%mod;
  79. val[id[son]]=(w[son]+val[id[ch[son][]]]+val[id[ch[son][]]])%mod;
  80. update(id[x],,n,,val[id[x]]);//修改线段树上的值
  81. update(id[son],,n,,val[id[son]]);
  82. getinv(x);getinv(son);
  83. }
  84. int main(){
  85. int u,v,t,tcase=;
  86. scanf("%d",&t);
  87. while(t--){
  88. scanf("%d%d",&n,&m);
  89. memset(ch,,sizeof ch);
  90. memset(pre,,sizeof pre);
  91. w[]=val[]=dfs_clock=;
  92. for(int i=;i<=n;i++){
  93. scanf("%d%d%d",&w[i],&u,&v);
  94. ch[i][]=u,ch[i][]=v;
  95. if(u) pre[u]=i;
  96. if(v) pre[u]=i;
  97. }
  98. for(int i=;i<=n;i++)if(pre[i]==) {dfs(i);break;}
  99. build(,n,);
  100. printf("Case #%d:\n",++tcase);
  101. while(m--){
  102. scanf("%d%d",&u,&v);
  103. if(u==) printf("%lld\n",query(lx[v],rx[v],,n,));
  104. else rotate(v,u);
  105. }
  106. }
  107. }

hdu4942线段树模拟rotate操作+中序遍历 回头再做的更多相关文章

  1. POJ 2828.Buy Tickets-完全版线段树(单点更新、逆序遍历查询)

    POJ2828.Buy Tickets 这个题是插队问题,每次有人插队的时候,其后的所有数据都要进行更新,如果我们反着推,就可以把所有的数据都安排好并且不用再对已插入的数据进行更新,因为逆序处理的话所 ...

  2. lintcode: 中序遍历和后序遍历树构造二叉树

    题目 中序遍历和后序遍历树构造二叉树 根据中序遍历和后序遍历树构造二叉树 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2] 返回如下的树: 2 /  \ 1    3 注意 你可 ...

  3. LintCode-72.中序遍历和后序遍历树构造二叉树

    中序遍历和后序遍历树构造二叉树 根据中序遍历和后序遍历树构造二叉树 注意事项 你可以假设树中不存在相同数值的节点 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2] 返回如下的树: ...

  4. [LeetCode] 538. 把二叉搜索树转换为累加树 ☆(中序遍历变形)

    把二叉搜索树转换为累加树 描述 给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater Tree),使得每个节点的值是原来的节点值加上所有大于它的节点值之和. ...

  5. [jzoj 5662] 尺树寸泓 解题报告 (线段树+中序遍历)

    interlinkage: https://jzoj.net/senior/#contest/show/2703/1 description: solution: 发现$dfs$序不好维护 注意到这是 ...

  6. hdu_5818_Joint Stacks(线段树模拟)

    题目链接:hdu_5818_Joint Stacks 题意: 给你两个栈,多了个合并操作,然后让你模拟 题解: 很容易想到O(1)的单个栈操作,O(n)的合并操作,这样肯定超时,所以我们要将时间复杂度 ...

  7. 线段树区间更新操作及Lazy思想(详解)

    此题题意很好懂:  给你N个数,Q个操作,操作有两种,‘Q a b ’是询问a~b这段数的和,‘C a b c’是把a~b这段数都加上c. 需要用到线段树的,update:成段增减,query:区间求 ...

  8. 根据 中序遍历 和 后序遍历构造树(Presentation)(C++)

    好不容易又到周五了,周末终于可以休息休息了.写这一篇随笔只是心血来潮,下午问了一位朋友PAT考的如何,顺便看一下他考的试题,里面有最后一道题,是关于给出中序遍历和后序遍历然后求一个层次遍历.等等,我找 ...

  9. hdu 3436 线段树 一顿操作

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

随机推荐

  1. elasticsearch-head安装及启动

    head是用于监控Elasticsearch状态的客户端插件,包括数据可视化,增删改查工具,es语句的可视化等等. 5.0之后的安装方式如下: git clone git://github.com/m ...

  2. Nginx使用Location匹配URL进行伪静态

    基础知识 Nginx location 配置语法 1. location [ = | ~ | ~* | ^~ ] uri { ... } 2. location @name { ... } locat ...

  3. SQL Server 日期和时间类型

    在Microsoft SQL Server的类型系统中,使用 date 表示日期类型,使用time表示时间类型,使用DateTime和DateTime2表示日期和时间的组合,DateTime2是Dat ...

  4. GET_WHEEL_DELTA_WPARAM宏在C#

    1.高位字,署名: ((short)(wParam>>16)) 2. 为了获得最大的清晰,我会定义一组这样的函数: internal static class NativeMethods ...

  5. 网络类型IPv4和IPv6什么意思?区别?

    在windows 7以上系统中,在设置本地IP地址的时候经常会看到同事含有IPV4协议项与IPV6协议项,并不同于以往windows xp系统中仅有TCP/IP协议项,不少朋友都觉得比较奇怪,询问编辑 ...

  6. EntityFramework用法探索(八)事务处理

    使用 前文中描述的Retail示例 ,在Customer对象的Mapping中设置Name属性:我们构造一个有效的Customer对象,再构造一个无效的Name属性为空的对象. DomainModel ...

  7. 2018-2019-2 网络对抗技术 20165227 Exp4 恶意代码分析

    2018-2019-2 网络对抗技术 20165227 Exp4 恶意代码分析 实验步骤: 使用的设备:Win7(虚拟机).kali(虚拟机) 实验一:使用如计划任务,每隔一分钟记录自己的电脑有哪些程 ...

  8. weblogic基本目录介绍,位数查看,启动与发布项目,修改JVM参数,设置项目为默认项目

    这里的基本目录%base%表示安装目录,如我的目录为:E:/weblogic就是%base% 1.weblogic目录介绍 weblogic主要的目录介绍: 1.日志目录: 每个domain(域)都有 ...

  9. Dom4j向XML中增加节点与属性——(四)

    先获取到节点,然后在节点山添加Element 添加节点 添加属性 设置开始标签与结束标签的值book.addElement("描述").addAttribute("nam ...

  10. Dubbo服务容错(整合hystrix)

    简介:Hystrix旨在通过控制那些访问远程系统.服务和第三方库的节点从而对延迟和故障提供更强大的容错能力,Hystrix具备拥有回退机制和断路器功能的线程和信号隔离.请求缓存和请求打包以及监控和配置 ...