Description

Input

Output

Sample Input

3 4
1 2 3
1 0 0
1 0 0
2 1
0 1
2 2
2 1

Sample Output

3
6
2

Data Constraint

题解

  • 每次子树和只有 2 个点会修改
  • 旋转会导致统计子树的答案会比较麻烦
  • 而这是一棵平衡树,中序遍历在平衡树中的相对位置不会变
  • 而在中序遍历中,一个点的子树也是一个区间
  • 所以,我们可以把中序遍历搞出来,维护每个子树相对应的区间
  • 用线段树维护就可以了

代码

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #define mo 1000000007
  6 using namespace std;
  7 struct data{ int l,r; }son[2000010];
  8 struct splay{ int l,r;long long mul; }tree[2000010*4];
  9 long long f[2000010],sum[2000010],a[2000010],fa[2000010],size[2000010],num[2000010],numl[2000010],ans;
 10 int n,q,opt,x,tot;
 11 void dfs(int x)
 12 {
 13     size[x]=1;
 14     if (son[x].l) dfs(son[x].l);
 15     num[++tot]=x; numl[x]=tot;
 16     if (son[x].r) dfs(son[x].r);
 17     sum[x]=(sum[son[x].l]+sum[son[x].r]+a[x])%mo;
 18     f[x]=((f[son[x].l]*f[son[x].r])%mo*sum[x])%mo;
 19     size[x]+=size[son[x].l]+size[son[x].r];
 20 }
 21 void build(int dep,int l,int r)
 22 {
 23     tree[dep].l=l; tree[dep].r=r;
 24     if (l==r)
 25     {
 26         tree[dep].mul=sum[num[l]];
 27         return;
 28     }
 29     int mid=(l+r)/2;
 30     build(dep*2,l,mid);
 31     build(dep*2+1,mid+1,r);
 32     tree[dep].mul=(tree[dep*2].mul*tree[dep*2+1].mul)%mo;
 33 }
 34 void change(int dep,int l,int r,int x,int y)
 35 {
 36     if (l==r)
 37     {
 38         tree[dep].mul=y;
 39         return;
 40     }
 41     int mid=(l+r)/2;
 42     if (mid>=x) change(dep*2,l,mid,x,y);
 43     else change(dep*2+1,mid+1,r,x,y);
 44     tree[dep].mul=(tree[dep*2].mul*tree[dep*2+1].mul)%mo;
 45 }
 46 void mul(int dep,int l,int r,int x,int y)
 47 {
 48     if (l==x&&y==r)
 49     {
 50         ans*=tree[dep].mul;
 51         ans=ans%mo;
 52         return;
 53     }
 54     int mid=(l+r)/2;
 55     if (y<=mid) mul(dep*2,l,mid,x,y);
 56     else if (x>mid) mul(dep*2+1,mid+1,r,x,y);
 57     else mul(dep*2,l,mid,x,mid),mul(dep*2+1,mid+1,r,mid+1,y);
 58 }
 59 int rrotate(int x)
 60 {
 61     int y=son[x].l;
 62     if (son[fa[x]].l==x) son[fa[x]].l=y; else son[fa[x]].r=y;
 63     int u=size[y];
 64     size[y]=size[x];
 65     size[x]=size[x]-u+size[son[y].r];
 66     fa[son[y].r]=x;
 67     fa[y]=fa[x];
 68     fa[x]=y;
 69     son[x].l=son[y].r;
 70     son[y].r=x;
 71     sum[x]=(sum[son[x].l]+sum[son[x].r]+a[x])%mo;
 72     change(1,1,n,numl[x],sum[x]);
 73     sum[y]=(sum[son[y].l]+sum[son[y].r]+a[y])%mo;
 74     change(1,1,n,numl[y],sum[y]);
 75 }
 76 int lrotate(int x)
 77 {
 78     int y=son[x].r;
 79     if (son[fa[x]].l==x) son[fa[x]].l=y; else son[fa[x]].r=y;
 80     int u=size[y];
 81     size[y]=size[x];
 82     size[x]=size[x]-u+size[son[y].l];
 83     fa[son[y].l]=x;
 84     fa[y]=fa[x];
 85     fa[x]=y;
 86     son[x].r=son[y].l;
 87     son[y].l=x;
 88     sum[x]=(sum[son[x].l]+sum[son[x].r]+a[x])%mo;
 89     change(1,1,n,numl[x],sum[x]);
 90     sum[y]=(sum[son[y].l]+sum[son[y].r]+a[y])%mo;
 91     change(1,1,n,numl[y],sum[y]);
 92 }
 93 int main()
 94 {
 95     //freopen("splay.in","r",stdin);
 96     //freopen("splay.out","w",stdout);
 97     scanf("%d%d",&n,&q);
 98     f[0]=1;
 99     for (int i=0;i<2000010;i++) tree[i].mul=1;
100     for (int i=1;i<=n;i++)
101     {
102         scanf("%d%d%d",&a[i],&son[i].l,&son[i].r);
103         f[i]=1;
104         fa[son[i].l]=i; fa[son[i].r]=i;
105     }
106     dfs(1);
107     build(1,1,n);
108     for (int i=1;i<=q;i++)
109     {
110         scanf("%d%d",&opt,&x);
111         if (opt==0) if (son[x].l) rrotate(x);
112         if (opt==1) if (son[x].r) lrotate(x);
113         if (opt==2)
114         {
115             ans=1;
116             mul(1,1,n,numl[x]-size[son[x].l],numl[x]+size[son[x].r]);
117             printf("%lld\n",ans);
118         }
119     }
120     return 0;
121 }

转载于:https://www.cnblogs.com/Comfortable/p/8893450.html

[Splay][线段树] jzoj P5662 尺树寸泓相关推荐

  1. splay + 线段树 ---- P3765总统选举 [带修改的动态区间众数 摩尔投票+n棵splay]

    题目链接 题目大意: 解题思路: 1.摩尔投票法: 题意是找n个数内出现次数大于n/2的数 保证存在这个数用的方法叫做摩尔投票法 首先我们注意到这样一个现象: 在任何数组中,出现次数大于该数组长度一半 ...

  2. CodeForces 85D Sum of Medians Splay | 线段树

    Sum of Medians 题解: 对于这个题目,先想到是建立5棵Splay,然后每次更新把后面一段区间的树切下来,然后再转圈圈把切下来的树和别的树合并. 但是感觉写起来太麻烦就放弃了. 建立5棵线 ...

  3. [线段树] Jzoj P1214 项链工厂

    Description T 公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱.最近T 公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中 ...

  4. [权值线段树] Jzoj P4270 魔道研究

    Description "我希望能使用更多的魔法.不对,是预定能使用啦.最终我要被大家称呼为大魔法使.为此我决定不惜一切努力." --<The Grimoire of Mar ...

  5. 二逼平衡树——树套树(线段树套Splay平衡树)

    题面 Bzoj3196 解析 线段树和Splay两棵树套在一起,常数直逼inf,但最终侥幸过了 思路还是比较简单, 在原数组维护一个下标线段树,再在每一个线段树节点,维护一个对应区间的权值Splay. ...

  6. 【POJ】2828 Buy Tickets(线段树+特殊的技巧/splay)

    http://poj.org/problem?id=2828 一开始敲了个splay,直接模拟. tle了.. 常数太大.. 好吧,说是用线段树.. 而且思想很拽.. (貌似很久以前写过貌似的,,) ...

  7. 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 2271  Solved: 935 [Submit][St ...

  8. [BZOJ4825][HNOI2017]单旋(线段树+Splay)

    4825: [Hnoi2017]单旋 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 667  Solved: 342 [Submit][Status ...

  9. POJ - 2828 Buy Tickets(线段树+思维/Splay+模拟)

    题目链接:点击查看 题目大意:给出n个人,一个队列,一开始队列是空的,每个人加入的时候都会插入到指定位置pos的后面,即插队,问最后队列的排列情况是怎么样的 题目分析:一开始很难想到是线段树的题目,毕 ...

最新文章

  1. deeplearning模型库
  2. The NVIDIA driver on your system is too old
  3. python 自动化-五大自动化测试的Python框架
  4. tableau必知必会之如何在Tableau server中实现工作薄的自动刷新
  5. 【译】The challenge of verification and testing of machine learning
  6. MYSQL 查看表上索引的 1 方法
  7. 程序员工作3年只涨2千,你不知道程序员有多难!
  8. 员工主动辞职公司也要支付经济补偿金的17种情况
  9. 通过配置IP SLA跟踪静态路由
  10. 反射机制,类的加载机制,和注解的配置参数的结合使用详解
  11. Can I use 前端兼容性自查工具
  12. 关于hadoop运行成功但是无法链接web页面
  13. 为什么优秀的程序员bug很少?因为他们……
  14. 关键词挖掘的方法和技巧
  15. C语言中的while的意思,C语言中while是什么意思
  16. 转:POI操作Excel:cell的背景颜色类型
  17. UE5+VS2022编译Lyra实例项目
  18. 专访星陀资本合伙人秦毅:秉持理性投资之道,着眼于技术应用层
  19. 实战:使用yolov3完成肺结节检测(Luna16数据集)及肺实质分割
  20. 手机nfc_如何在Android中编写NFC标签

热门文章

  1. Redis源码剖析(六)事务模块
  2. 16位汇编 寄存器的操作
  3. ubuntu声音太小的解决方案
  4. 双向链表简单实现及图示
  5. CF-1023F.Mobile Phone Network(并查集缩点)
  6. 记录 之 一个小bug:Unsupported syntax ‘Starred‘
  7. 巴菲特:人生赢家,都是稳中求生,稳中求胜
  8. Pwn环境配置(一)——安装虚拟机
  9. 关于优酷开放SDK中setOnRealVideoStartListener
  10. .Net Core Nuget还原失败