hdu4942线段树模拟rotate操作+中序遍历 回头再做
很有意思的题目,详细题解看这里 https://blog.csdn.net/qian99/article/details/38536559
自己的代码不知道哪里出了点问题
/*
rotate操作不会改变树的中序遍历结果,将初始的树按中序遍历结果拍扁在线段树上,
线段树结点维护每个结点的子树范围,自身权值和子树权值
*/
#pragma comment(linker,"/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
#define mod 1000000007
#define ll long long
int ch[maxn][],pre[maxn],n,m;
int dfs_clock,lx[maxn],rx[maxn],w[maxn],id[maxn];//结点在线段树中的位置
ll val[maxn];
void dfs(int u){
if(ch[u][]) dfs(ch[u][]);//先遍历左子树
id[u]=++dfs_clock;val[dfs_clock]=w[u];//访问当前结点
if(ch[u][]){
lx[u]=lx[ch[u][]];//左边界
val[id[u]]+=val[id[ch[u][]]];
}
else lx[u]=id[u]; if(ch[u][]) dfs(ch[u][]);//在访问右子树
if(ch[u][]) {
rx[u]=rx[ch[u][]];//右边界
val[id[u]]+=val[id[ch[u][]]];
}
else rx[u]=id[u];
val[id[u]]%=mod;
}
inline void getinv(int x){
if(ch[x][]) lx[x]=lx[ch[x][]];
else lx[x]=id[x];
if(ch[x][]) rx[x]=rx[ch[x][]];
else rx[x]=id[x];
} //线段树部分
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
ll mul[maxn<<];
inline void pushup(int rt){
mul[rt]=mul[rt<<]*mul[rt<<|]%mod;
}
void build(int l,int r,int rt){
if(l==r){mul[rt]=val[l];return;}
int m=l+r>>;
build(lson);
build(rson);
pushup(rt);
}
ll query(int L,int R,int l,int r,int rt){//查询区间[L,R]的乘积
if(L<=l && R>=r) return mul[rt];
int m=l+r>>;
ll res=;
if(L<=m) res=query(L,R,lson);
if(R>m) res*=query(L,R,rson),res%=mod;
return res;
}
void update(int pos,int l,int r,int rt,int val){
if(l==r){mul[rt]=val;return;}
int m=l+r>>;
if(pos<=m) update(pos,lson,val);
else update(pos,rson,val);
pushup(rt);
} void rotate(int x,int kind){//右转是0,左转是1,和伸展树操作刚好相反。。
int son=ch[x][kind];
if(son==) return;
ch[x][kind]=ch[son][kind^];
if(ch[son][kind^]) pre[ch[son][kind^]]=x;
if(pre[x]) ch[pre[x]][ch[pre[x]][]==x]=son;
pre[son]=pre[x];
ch[son][kind^]=x;
pre[x]=son; val[id[x]]=(w[x]+val[id[ch[x][]]]+val[id[ch[x][]]])%mod;
val[id[son]]=(w[son]+val[id[ch[son][]]]+val[id[ch[son][]]])%mod;
update(id[x],,n,,val[id[x]]);//修改线段树上的值
update(id[son],,n,,val[id[son]]);
getinv(x);getinv(son);
}
int main(){
int u,v,t,tcase=;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
memset(ch,,sizeof ch);
memset(pre,,sizeof pre);
w[]=val[]=dfs_clock=;
for(int i=;i<=n;i++){
scanf("%d%d%d",&w[i],&u,&v);
ch[i][]=u,ch[i][]=v;
if(u) pre[u]=i;
if(v) pre[u]=i;
}
for(int i=;i<=n;i++)if(pre[i]==) {dfs(i);break;}
build(,n,);
printf("Case #%d:\n",++tcase);
while(m--){
scanf("%d%d",&u,&v);
if(u==) printf("%lld\n",query(lx[v],rx[v],,n,));
else rotate(v,u);
}
}
}
hdu4942线段树模拟rotate操作+中序遍历 回头再做的更多相关文章
- POJ 2828.Buy Tickets-完全版线段树(单点更新、逆序遍历查询)
POJ2828.Buy Tickets 这个题是插队问题,每次有人插队的时候,其后的所有数据都要进行更新,如果我们反着推,就可以把所有的数据都安排好并且不用再对已插入的数据进行更新,因为逆序处理的话所 ...
- lintcode: 中序遍历和后序遍历树构造二叉树
题目 中序遍历和后序遍历树构造二叉树 根据中序遍历和后序遍历树构造二叉树 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2] 返回如下的树: 2 / \ 1 3 注意 你可 ...
- LintCode-72.中序遍历和后序遍历树构造二叉树
中序遍历和后序遍历树构造二叉树 根据中序遍历和后序遍历树构造二叉树 注意事项 你可以假设树中不存在相同数值的节点 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2] 返回如下的树: ...
- [LeetCode] 538. 把二叉搜索树转换为累加树 ☆(中序遍历变形)
把二叉搜索树转换为累加树 描述 给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater Tree),使得每个节点的值是原来的节点值加上所有大于它的节点值之和. ...
- [jzoj 5662] 尺树寸泓 解题报告 (线段树+中序遍历)
interlinkage: https://jzoj.net/senior/#contest/show/2703/1 description: solution: 发现$dfs$序不好维护 注意到这是 ...
- hdu_5818_Joint Stacks(线段树模拟)
题目链接:hdu_5818_Joint Stacks 题意: 给你两个栈,多了个合并操作,然后让你模拟 题解: 很容易想到O(1)的单个栈操作,O(n)的合并操作,这样肯定超时,所以我们要将时间复杂度 ...
- 线段树区间更新操作及Lazy思想(详解)
此题题意很好懂: 给你N个数,Q个操作,操作有两种,‘Q a b ’是询问a~b这段数的和,‘C a b c’是把a~b这段数都加上c. 需要用到线段树的,update:成段增减,query:区间求 ...
- 根据 中序遍历 和 后序遍历构造树(Presentation)(C++)
好不容易又到周五了,周末终于可以休息休息了.写这一篇随笔只是心血来潮,下午问了一位朋友PAT考的如何,顺便看一下他考的试题,里面有最后一道题,是关于给出中序遍历和后序遍历然后求一个层次遍历.等等,我找 ...
- hdu 3436 线段树 一顿操作
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) To ...
随机推荐
- django中命令行调试程序
(1)进入到程序manage.py所在的目录下 (2)python manage.py shell 这样可在命令行中引入models.views.class等所有的包,然后进行命令行试运行.
- 盖得化工----requests/bs4---采集二级网址
Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...
- Study 6 —— 字体和段落属性
字体风格{font-style:normal | italic | oblique | inherit字体复合属性{font:font-style font-variant font-weight f ...
- 神级程序员通过两句话带你完全掌握Python最难知识点——元类!
千万不要被所谓"元类是99%的python程序员不会用到的特性"这类的说辞吓住.因为 每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生 ...
- luogu 4401 矿工配餐 多维dp
五维dp,记忆化搜索会MLE超内存,所以用滚动数组,十分经典 五维dp #include <bits/stdc++.h> using namespace std; ; ][][][],la ...
- luogu P3760 [TJOI2017]异或和
传送门 对于每个二进制位考虑有多少区间和这一位上为1 从前往后扫每个前缀和,如果当前这个前缀和某一个二进制位上为1,因为区间和由这个前缀和减去前面的前缀和得来,如果减去了这一位为0的前缀和,那么 减去 ...
- Thymeleaf在IDEA中的使用
让html页面的thymeleaf 标签不显示刺眼的红色波浪线,解决方法如下 IDEA官方链接:https://www.jetbrains.com/help/idea/2017.1/thymeleaf ...
- F - 回转寿司 (权值线段树)
题目链接:https://cn.vjudge.net/contest/281960#problem/F 题目大意:中文题目 具体思路:权值线段树,我们每次寻找的是满足 (i<j) L< ...
- python基础知识~配置文件模块
一 配置文件模块 import ConfigParser ->导入模块 conf = ConfigParser.ConfigParser() ->初始化类二 系统函数 conf.r ...
- Java中ArrayList循环遍历并删除元素的陷阱
ava中的ArrayList循环遍历并且删除元素时经常不小心掉坑里,昨天又碰到了,感觉有必要单独写篇文章记一下. 先写个测试代码: import java.util.ArrayList; public ...