[Splay][线段树] jzoj P5662 尺树寸泓
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 尺树寸泓相关推荐
- splay + 线段树 ---- P3765总统选举 [带修改的动态区间众数 摩尔投票+n棵splay]
题目链接 题目大意: 解题思路: 1.摩尔投票法: 题意是找n个数内出现次数大于n/2的数 保证存在这个数用的方法叫做摩尔投票法 首先我们注意到这样一个现象: 在任何数组中,出现次数大于该数组长度一半 ...
- CodeForces 85D Sum of Medians Splay | 线段树
Sum of Medians 题解: 对于这个题目,先想到是建立5棵Splay,然后每次更新把后面一段区间的树切下来,然后再转圈圈把切下来的树和别的树合并. 但是感觉写起来太麻烦就放弃了. 建立5棵线 ...
- [线段树] Jzoj P1214 项链工厂
Description T 公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖.款式多样.价格适中,广受青年人的喜爱.最近T 公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中 ...
- [权值线段树] Jzoj P4270 魔道研究
Description "我希望能使用更多的魔法.不对,是预定能使用啦.最终我要被大家称呼为大魔法使.为此我决定不惜一切努力." --<The Grimoire of Mar ...
- 二逼平衡树——树套树(线段树套Splay平衡树)
题面 Bzoj3196 解析 线段树和Splay两棵树套在一起,常数直逼inf,但最终侥幸过了 思路还是比较简单, 在原数组维护一个下标线段树,再在每一个线段树节点,维护一个对应区间的权值Splay. ...
- 【POJ】2828 Buy Tickets(线段树+特殊的技巧/splay)
http://poj.org/problem?id=2828 一开始敲了个splay,直接模拟. tle了.. 常数太大.. 好吧,说是用线段树.. 而且思想很拽.. (貌似很久以前写过貌似的,,) ...
- 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 2271 Solved: 935 [Submit][St ...
- [BZOJ4825][HNOI2017]单旋(线段树+Splay)
4825: [Hnoi2017]单旋 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 667 Solved: 342 [Submit][Status ...
- POJ - 2828 Buy Tickets(线段树+思维/Splay+模拟)
题目链接:点击查看 题目大意:给出n个人,一个队列,一开始队列是空的,每个人加入的时候都会插入到指定位置pos的后面,即插队,问最后队列的排列情况是怎么样的 题目分析:一开始很难想到是线段树的题目,毕 ...
最新文章
- deeplearning模型库
- The NVIDIA driver on your system is too old
- python 自动化-五大自动化测试的Python框架
- tableau必知必会之如何在Tableau server中实现工作薄的自动刷新
- 【译】The challenge of verification and testing of machine learning
- MYSQL 查看表上索引的 1 方法
- 程序员工作3年只涨2千,你不知道程序员有多难!
- 员工主动辞职公司也要支付经济补偿金的17种情况
- 通过配置IP SLA跟踪静态路由
- 反射机制,类的加载机制,和注解的配置参数的结合使用详解
- Can I use 前端兼容性自查工具
- 关于hadoop运行成功但是无法链接web页面
- 为什么优秀的程序员bug很少?因为他们……
- 关键词挖掘的方法和技巧
- C语言中的while的意思,C语言中while是什么意思
- 转:POI操作Excel:cell的背景颜色类型
- UE5+VS2022编译Lyra实例项目
- 专访星陀资本合伙人秦毅:秉持理性投资之道,着眼于技术应用层
- 实战:使用yolov3完成肺结节检测(Luna16数据集)及肺实质分割
- 手机nfc_如何在Android中编写NFC标签