没有用到任何算法,代码只有60+行,但是细节多如牛毛,各种分类讨论必须全部想清楚才行。

https://www.cnblogs.com/xiejiadong/p/6811289.html

 #include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
typedef long long ll;
using namespace std; const int N=;
ll n,nd,tot,m,u,l,r,S,mid[N],ls[N],rs[N],sm[N][],dep[N],sd[N][],fa[N][],L[N],R[N],pos[N]; bool bel(int x,int y){ return L[x]>=L[y] && R[x]<=R[y]; }
ll lca(ll a,ll b){
if (bel(a,b)) return b;
if (bel(b,a)) return a;
ll now=a;
for (ll i=S; ~i; i--) if (fa[now][i] && !bel(b,fa[now][i])) now=fa[now][i];
return fa[now][];
} void Dfs(ll x){
if (!ls[x]) return;
sm[rs[x]][]=sm[x][]; sm[rs[x]][]=sm[x][]+;
sm[ls[x]][]=sm[x][]+; sm[ls[x]][]=sm[x][];
dep[ls[x]]=dep[rs[x]]=dep[x]+;
sd[rs[x]][]=sd[x][]; sd[rs[x]][]=sd[x][]+dep[x]+;
sd[ls[x]][]=sd[x][]+dep[x]+; sd[ls[x]][]=sd[x][];
Dfs(ls[x]); Dfs(rs[x]);
} ll dfs(ll l,ll r){
ll x=++nd; L[x]=l; R[x]=r;
for (ll i=; fa[fa[x][i]][i]; i++) fa[x][i+]=fa[fa[x][i]][i];
if (l==r) return pos[l]=x;
ll m=mid[tot++];
fa[nd+][]=x; ls[x]=dfs(l,m);
fa[nd+][]=x; rs[x]=dfs(m+,r);
return x;
} ll getl(ll l){
ll lc=lca(l,u),x=dep[lc]*(sm[l][]-sm[lc][])+(bel(l,ls[lc]) && lc!=u)+sd[lc][]-sm[lc][];
return sd[l][]+sm[l][]*dep[u]-x*;
} ll getr(ll r){
ll lc=lca(r,u),x=dep[lc]*(sm[r][]-sm[lc][])+(bel(r,rs[lc]) && lc!=u)+sd[lc][]-sm[lc][];
return sd[r][]+sm[r][]*dep[u]-x*;
} int main(){
freopen("segment.in","r",stdin);
freopen("segment.out","w",stdout);
scanf("%lld",&n);
for (ll i=; i<=n; i<<=) S++;
for (ll i=; i<n; i++) scanf("%lld",&mid[i]);
tot=; dfs(,n); Dfs();
for (scanf("%lld",&m); m--; ){
scanf("%lld%lld%lld",&u,&l,&r); l--; r++;
if (!l && r>n) { printf("%lld\n",dep[u]); continue; }
ll ans=;
if (l) ans+=getl(pos[l])-((r<=n)?getl(ls[lca(pos[l],pos[r])]):);
if (r<=n) ans+=getr(pos[r])-(l?getr(rs[lca(pos[l],pos[r])]):);
printf("%lld\n",ans);
}
return ;
}

[BZOJ4876][ZJOI2017]线段树的更多相关文章

  1. ZJOI2017线段树

    ZJOI2017线段树 题意: ​ 给你一颗广义线段树,太长了,自己去看. 题解: ​ 直接上zkw那一套,把闭区间换成开区间,就是把取\([l,r]\),变成取\([l-1,l-1],[r+1,r+ ...

  2. 「ZJOI2017」树状数组(二维线段树)

    「ZJOI2017」树状数组(二维线段树) 吉老师的题目真是难想... 代码中求的是 \(\sum_{i=l-1}^{r-1}a_i\),而实际求的是 \(\sum_{i=l}^{r}a_i\),所以 ...

  3. [BZOJ4785][ZJOI2017]树状数组(概率+二维线段树)

    4785: [Zjoi2017]树状数组 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 297  Solved: 195[Submit][Status ...

  4. 【BZOJ4785】[Zjoi2017]树状数组 树套树(二维线段树)

    [BZOJ4785][Zjoi2017]树状数组 Description 漆黑的晚上,九条可怜躺在床上辗转反侧.难以入眠的她想起了若干年前她的一次悲惨的OI 比赛经历.那是一道基础的树状数组题.给出一 ...

  5. Loj #2570. 「ZJOI2017」线段树

    Loj #2570. 「ZJOI2017」线段树 题目描述 线段树是九条可怜很喜欢的一个数据结构,它拥有着简单的结构.优秀的复杂度与强大的功能,因此可怜曾经花了很长时间研究线段树的一些性质. 最近可怜 ...

  6. bzoj4785:[ZJOI2017]树状数组:二维线段树

    分析: "如果你对树状数组比较熟悉,不难发现可怜求的是后缀和" 设数列为\(A\),那么可怜求的就是\(A_{l-1}\)到\(A_{r-1}\)的和(即\(l-1\)的后缀减\( ...

  7. 【UOJ295】【ZJOI2017】线段树 倍增

    题目大意 http://uoj.ac/problem/295 题解 考虑像 zkw 线段树一样,从 \([l-1,l-1],[r+1,r+1]\) 这两个区间开始往上跳,直到两个指针碰到一起为止. 先 ...

  8. BZOJ4785 ZJOI2017树状数组(概率+二维线段树)

    可以发现这个写挂的树状数组求的是后缀和.find(r)-find(l-1)在模2意义下实际上查询的是l-1~r-1的和,而本来要查询的是l~r的和.也就是说,若结果正确,则a[l-1]=a[r](mo ...

  9. BZOJ 4785 [Zjoi2017]树状数组 | 二维线段树

    题目链接 BZOJ 4785 题解 这道题真是令人头秃 = = 可以看出题面中的九条可怜把求前缀和写成了求后缀和,然后他求的区间和却仍然是sum[r] ^ sum[l - 1],实际上求的是闭区间[l ...

随机推荐

  1. NYOJ 1063 生活的烦恼 (二叉树)

    题目链接 描述 生活的暑假刚集训开始,他要决心学好字典树,二叉树,线段树和各种树,但生活在OJ上刷题的时候就遇到了一个特别烦恼的问题.那当然就是他最喜欢的二二叉树咯!题目是这样的:给你一颗非空的二叉树 ...

  2. DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead extract-text-webpack-plugin 提取css报错

    深入浅出Webpack 1-5 使用pulugin extract-text-webpack-plugin 提取css报错 DeprecationWarning: Tapable.plugin is ...

  3. .net APIHelper client获取数据

    using Newtonsoft.Json; using System.Net.Http.Headers; public static class APIHepler { public static ...

  4. Lithium中关键特性更新

    Lithium中关键特性更新 1. Lithium特性更新概述 Lithium相对于Helium更新特性共27项,其中原有特性提升或增强13项,新增特性14项,如下表所示 特性类型 相对于Helium ...

  5. spring-boot-资源处理

    WebMvcConfigurerAdapter 使用 1.实现 HandlerInterceptorAdapter 2.添加拦截器 重写WebMvcConfigurerAdapter中的addInte ...

  6. 学习Python函数笔记之二(内置函数)

    ---恢复内容开始--- 1.内置函数:取绝对值函数abs() 2.内置函数:取最大值max(),取最小值min() 3.内置函数:len()是获取序列的长度 4.内置函数:divmod(x,y),返 ...

  7. Fedora8 U盘安装

    (一)分区 在XP下"我的电脑“管理功能,对硬盘分区,目的是从逻辑分区中拿出20G空间,分成3个盘(必须为逻辑盘): (1)512MB   用作Linux swap分区: (2)200MB  ...

  8. [MySQL] AUTO_INCREMENT lock Handing in InnoDB

    MySQL AUTO_INCREMENT lock Handing in InnoDB 在MySQL的表设计中很普遍的使用自增长字段作为表主键, 实际生产中我们也是这样约束业务开发同学的, 其中的优势 ...

  9. 微信开发,调用js-SDK接口

    微信开发,调用js-SDK接口<!DOCTYPE html><html><head lang="en"> <meta charset=&q ...

  10. linux下查看资源使用情况

    //查看占用内存最多的前K的程序ps aux | sort -k4nr | head -K //查看占用CPU最多的前K的程序 ps aux | sort -k3nr | head -K