2019牛客暑期多校训练营(第八场)I-Inner World DFS序+主席树(扫描线也可)
题意:初始有n棵树,每棵树都只有1个n号节点,现在有m次添加操作,每次操作是将$[l,r]$范围内的树的$u$节点后面添加一个$v$节点。每个v节点只会被添加一次。
然后是q次询问,输出$[l,r]$范围内的树$x$节点的子树大小之和。
思路:由于每个节点被当成子节点添加到树上只会被添加一次,所以假设直接将节点连到一棵树上,按照dfs排序之后,x节点的子树dfs序必定是连续的。
考虑主席树,我们以dfs序为主席树的版本,每个节点就让$(ql,qr)$之间的树加一,最后只需要将ou[x]和in[x]-1这两个版本之间的主席树相减即可。(代码在最下方)
另一个做法:考虑扫描线,我们还是先处理处dfs序,对于节点x的求解,我们可以分解成,减去x之前所有节点(ql,qr)的值,再加上ou[x]的(ql,qr)的值,就得到了我们要的答案。所以我们还是按dfs序处理线段树,将每一个节点的影响加入线段树后,再处理这个节点需要加减的地方即可。我自己没有写过扫描线版本,此处引用一位朋友的代码。
//这是扫描线的关键,此处的线段树就是一个普通的区间求和的线段树。
scanf("%d", &q);
for(int i = ; i <= q; i++) {
int x, l, r;
scanf("%d%d%d", &x, &l, &r);
V[in[x] - ].push_back(Qus{-, l, r, i});
V[ot[x]].push_back(Qus{, l, r, i});
}
for(int i = ; i <= idx; i++) {
Tree.update(L[rk[i]], R[rk[i]], , , n, );
for(auto t : V[i]) {
ans[t.id] += t.op * Tree.query(t.l, t.r, , n, );
}
}
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,b,a) for(int i=b;i>=a;i--)
#define clr(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pii pair<int,int >
using namespace std;
typedef long long ll;
ll rd()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
const int maxn=;
const int inf=0x3f3f3f3f;
int n,m,q,tot,root[maxn],l[maxn],r[maxn],in[maxn],ou[maxn],re[maxn],ti;
struct node{
int l,r;
ll sum,lazy;
}tr[maxn*];
vector<int >ve[maxn];
void dfs(int u){
in[u]=++ti;
re[ti]=u;
for(auto it:ve[u]){
dfs(it);
}
ou[u]=ti;
}
void update(int &rt,int pre,int l,int r,int ql,int qr,ll val){
tr[rt=++tot]=tr[pre];
tr[rt].sum+=(qr-ql+)*val;
if(ql<=l&&r<=qr){
tr[rt].lazy+=val;
return;
}
int mid=(l+r)>>;
if(ql<=mid)update(tr[rt].l,tr[pre].l,l,mid,ql,min(qr,mid),val);
if(mid<qr)update(tr[rt].r,tr[pre].r,mid+,r,max(mid+,ql),qr,val);
}
ll query(int rt,int pre,int l,int r,int ql,int qr,ll add){
if(ql<=l&&r<=qr){
return tr[rt].sum-tr[pre].sum+(r-l+)*add;
}
add+=tr[rt].lazy-tr[pre].lazy;
int mid=(l+r)>>;
ll res=;
if(ql<=mid)res+=query(tr[rt].l,tr[pre].l,l,mid,ql,qr,add);
if(mid<qr)res+=query(tr[rt].r,tr[pre].r,mid+,r,ql,qr,add);
return res; }
int main(){
cin>>n>>m;
l[]=,r[]=n;
for(int i=;i<=m;i++){
int u,v,x,y;
u=rd(),v=rd(),x=rd(),y=rd();
ve[u].pb(v);
l[v]=x,r[v]=y;
}
dfs();
for(int i=;i<=ti;i++){
int u=re[i];
update(root[i],root[i-],,n,l[u],r[u],);
}
cin>>q;
rep(i,,q){
int x,ql,qr;
x=rd(),ql=rd(),qr=rd();
printf("%lld\n",query(root[ou[x]],root[in[x]-],,n,ql,qr,));
}
}
2019牛客暑期多校训练营(第八场)I-Inner World DFS序+主席树(扫描线也可)的更多相关文章
- 2019牛客暑期多校训练营(第九场)H Cutting Bamboos(主席树+二分)
题意:n个竹子,有高度,q次询问,询问之间是独立的,每次查询输入l,r,x,y代表砍区间[l,r]]内的竹子砍y次,最后一次要砍成0,每次砍掉的总长度相同,问第x次砍的高度是多少. 既然每次要求砍掉的 ...
- 2019牛客暑期多校训练营(第一场)I Points Division(dp+线段树优化)
给你n个点,第i个点在的位置为(xi,yi),有两个属性值(ai,bi).现在让你把这n个点划分为A和B两个部分,使得最后不存在i∈A和j∈B,使得xi>=xj且yi<=yj.然后对于所有 ...
- 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)
题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9: 对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可. 后者mod=1e9,5才 ...
- 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)
链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...
- 2019牛客暑期多校训练营(第一场) B Integration (数学)
链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...
- 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)
链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...
- 2019牛客暑期多校训练营(第二场)F.Partition problem
链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...
- 2019牛客暑期多校训练营(第一场)A Equivalent Prefixes(单调栈/二分+分治)
链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 Two arrays u and v each with m distinct elements ...
- [状态压缩,折半搜索] 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem
链接:https://ac.nowcoder.com/acm/contest/889/D来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...
- 2019牛客暑期多校训练营(第二场)J-Subarray(思维)
>传送门< 前言 这题我前前后后看了三遍,每次都是把网上相关的博客和通过代码认真看了再思考,然并卵,最后终于第三遍也就是现在终于看懂了,其实懂了之后发现其实没有那么难,但是的的确确需要思维 ...
随机推荐
- LeetCode 分隔链表
题目链接:https://leetcode-cn.com/problems/partition-list/ 题目大意 略. 分析 空间复杂度 O(1) 的做法蛮有意思的,另外加头结点可以少写很多代码. ...
- 『Golang』—— 标准库之 time
... package main import ( "fmt" "time" ) func main() { time.AfterFunc(time.Milli ...
- JDK8之新特性扩展篇
之前分篇章讲了一些JKD8中添加的新特性,还有一些新特性这里也一并讲下. BASE64 base64编码解码已经被加入到了jdk8中了. import java.nio.charset.Standar ...
- Python中两大神器&exec() &eval()
一.神器1 -- 内置函数eval eval是python中的内置函数,它的作用是将字符串变为所对应的表达式,也相当于一个功能代码加双引号变为字符串,而eval又将字符串转为相应的功能,它在使用过程中 ...
- Ansible-随笔-7
扩展Ansible的插件系统. 有的时候,如果Ansible内置的插件无法满足需求时,我们可以自己编写新插件. 以下情况下可以考虑开发新插件: 1.除Paramiko.本机SSH.Local.Winr ...
- ES7/ES8 语法学习
作为一个前端开发者,感觉需要学习的东西贼多,ES6刚学会用没多久,又得学习了解ES7/ES8新增的东西,这里是看了大佬们文章的一点点总结以及摘抄的内容,给自己当笔记使用 内容转载自:https://w ...
- HttpURLConnection模拟登录学校的正方教务系统
教务系统登录界面 如图1-1 1-1 F12-->network查看登录教务系统需要参数: __VIEWSTAT txtUserName TextBox2 txtSecretCode Radio ...
- linux 档案 指令(鸟哥私房菜)
[ls -al] [ls -l --full-time] 显示文件完整的日期格式 [ls] 显示非隐藏档的文件信息 [ls -al] 显示所有文档信心.文档前面的 “”.“”表明该文档是隐藏档.eg. ...
- RHEL5/6/7中常用命令及命令之间的差异
System basics Task RHEL5 RHEL6 RHEL7 View subscription information /etc/sysconfig/rhn/systemid /etc/ ...
- B 树 B+树
拜读了 http://blog.csdn.net/v_july_v/article/details/6530142, 自己总结下: B树的出发点是为了解决磁盘IO慢的问题,尽量再一个磁盘块中提供更 ...