第一问不解释,对于第二问的处理,可以使用cdq分治,假设分治的询问区间是[L,R],那么我们对于标号在[L,mid]的修改操作赋予一个权值,因为在当前[L,R]中[L,mid]的修改操作只会对[mid+1,R]的询问操作,所以第i修改操作至少经过m-i的时间,因此赋予的权值是m-i,而对于[mid+1,R]区间中的询问操作,也赋予一个权值w-m,这里w为询问的数值,我们可以预处理出树的dfs序并维护一个树状数组,这样我们就可以把这些操作按权值从大到小插入或者询问,时间复杂度O(nlognlogn)。

  代码,运行时间差不多垫底。。(看了其他博主的题解貌似我想的复杂了。。。)

  1 #include<cstdio>
  2 #include<algorithm>
  3 #define N 500010
  4 #define lb(x) (x&-x)
  5 using namespace std;
  6 int dp,p[N],pre[N],tt[N],n,a,i,m,o,c[N],deep[N],fa[N];
  7 int L[N],R[N],ans[N];
  8 int s[N][20];
  9 struct g{
 10     int typ,l,r,w;
 11 }b[N];
 12 struct gg{
 13     int id,v;
 14 }w[N];
 15 void cc(int x,int w)
 16 {
 17     while (x<=o)
 18     {
 19         c[x]+=w;
 20         x+=lb(x);
 21     }
 22 }
 23 void dfs(int x)
 24 {
 25     int i=p[x];
 26     L[x]=++o;
 27     while (i)
 28     {
 29         fa[tt[i]]=x;
 30         deep[tt[i]]=deep[x]+1;
 31         dfs(tt[i]);
 32         i=pre[i];
 33     }
 34     R[x]=++o;
 35 }
 36 int lca(int x,int y)
 37 {
 38     if(deep[x]>deep[y])x^=y^=x^=y;
 39     int i;
 40     for(i=19;i>=0;i--)
 41     {
 42         if(deep[y]-deep[x]>=(1<<i))
 43         {
 44             y=s[y][i];
 45         }
 46     }
 47     if(x==y)return x;
 48     for(i=19;i>=0;i--)
 49     {
 50         if(s[x][i]!=s[y][i])
 51         {
 52             x=s[x][i];
 53             y=s[y][i];
 54         }
 55     }
 56     return fa[x];
 57 }
 58 int sum(int x)
 59 {
 60     int ans=0;
 61     while (x)
 62     {
 63         ans+=c[x];
 64         x-=lb(x);
 65     }
 66     return ans;
 67 }
 68 void link(int x,int y)
 69 {
 70     dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
 71 }
 72 bool cmp(gg a,gg b)
 73 {
 74     if (a.v==b.v)
 75     return a.id>b.id;
 76     return a.v>b.v;
 77 }
 78 void solve(int l,int r)
 79 {
 80     int m,i,tot=0;
 81     if (l>=r) return;
 82     m=(l+r)>>1;
 83     for (i=l;i<=m;i++)
 84     if (b[i].typ==2)
 85     {
 86         w[++tot].id=i;
 87         w[tot].v=m-i;
 88     }
 89     for (i=m+1;i<=r;i++)
 90     if (b[i].typ==1)
 91     {
 92         w[++tot].id=i;
 93         w[tot].v=b[i].w-(i-m);
 94     }
 95     sort(w+1,w+1+tot,cmp);
 96
 97     for (i=1;i<=tot;i++)
 98     if (w[i].id<=m)
 99     {
100         cc(L[b[w[i].id].w],1);
101         cc(R[b[w[i].id].w],-1);
102     }
103     else
104     {
105         int u=b[w[i].id].l;
106         int v=b[w[i].id].r;
107         int LCA=lca(u,v);
108         ans[w[i].id]+=sum(L[u])+sum(L[v])-sum(L[LCA])-sum(L[LCA]-1);
109     }
110     for (i=1;i<=tot;i++)
111     if (w[i].id<=m)
112     {
113         cc(L[b[w[i].id].w],-1);
114         cc(R[b[w[i].id].w],1);
115     }
116
117     solve(l,m);solve(m+1,r);
118 }
119
120 int main()
121 {
122     scanf("%d",&n);
123     for (i=1;i<=n;i++)
124     {
125         scanf("%d",&a);
126         if (a) link(a,i);
127     }
128     scanf("%d",&m);
129     for (i=1;i<=m;i++)
130     {
131         scanf("%d",&b[i].typ);
132         if (b[i].typ==1)
133         scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].w);
134         else scanf("%d",&b[i].w);
135     }
136     dfs(1);
137     for(i=1;i<=n;i++)s[i][0]=fa[i];
138     for(int h=1;h<20;h++)
139     {
140         for(i=1;i<=n;i++)
141         {
142             s[i][h]=s[s[i][h-1]][h-1];
143         }
144     }
145     solve(1,m);
146     for (i=1;i<=m;i++)
147     if (b[i].typ==1)
148     {
149         int Ans=lca(b[i].l,b[i].r);
150         Ans=deep[b[i].l]+deep[b[i].r]-2*deep[Ans]+1;
151         printf("%d %d\n",Ans,ans[i]);
152     }
153 }

转载于:https://www.cnblogs.com/fzmh/p/5397241.html

bzoj4448 [Scoi2015]情报传递相关推荐

  1. bzoj4448 SCOI2015 情报传递 message

    传送门bzoj4448 题解 离线之后构建树上主席树,每个点的线段树维护到根路径的信息,不用链剖(我的链剖只是拿来求\(\mathrm{lca}\)的),时空复杂度\(O(n\log{n})\). c ...

  2. [BZOJ4448][SCOI2015]情报传递[dfs序+树状数组]

    2操作可以转化成x的权值在i时刻变成了1,然后查询的操作相当于查询i - c[i] 时刻 x->y链上权值和 可以差分成 \[f(x) + f(y) - f(\text{lca}) - f(fa ...

  3. P4216 [SCOI2015]情报传递 LCA+树上主席树 离线操作

    题意: 给你一棵n个点的树,初始每个位置没有点权 有m次操作 1 x:让一个点从当前时刻开始,每秒操作点权++ 2 x y c:查询一条链中有多少点的点权大于c 其中每秒操作点权++就是指我每操作一次 ...

  4. 洛谷P4216 [SCOI2015]情报传递(树剖+主席树)

    传送门 我们可以进行离线处理,把每一个情报员的权值设为它开始收集情报的时间 那么设询问的时间为$t$,就是问路径上有多少个情报员的权值小于等于$t-c-1$ 这个只要用主席树上树就可以解决了,顺便用树 ...

  5. [SCOI2015]情报传递(主席树+lca)

    链接:https://ac.nowcoder.com/acm/problem/20570 来源:牛客网 输出描述: 对于每个传递情报任务输出一行,应包含两个整数,分别是参与传递情报的情报员个数和对该条 ...

  6. BZOJ4448:[SCO2015]情报传递

    题目大意:给你一棵树,有两种操作,一个是修改某个点的权值,另一个是询问两点之间的距离以及路径上小于某个值的数的个数. 询问两点之间距离直接lca即可,对于求个数的问题可以用主席树完成. 1 #incl ...

  7. 退役前的做题记录2.0

    退役前的做题记录2.0 最近在刷省选题......大致上是按照省份刷的. 不过上面的题目顺序是按照写题的顺序排列的,所以可能会有点乱哈. [BZOJ2823][AHOI2012]信号塔 最小圆覆盖,随 ...

  8. 2021-07-08~2021-07-22总结--zhengjun

    目录在此 2021-07-08~2021-07-22总结--zhengjun 7.8 考试过程 学习的算法 AC的题目 正在调试的题目 7.9 考试过程 学习的内容 AC的题目 正在调试的题目 7.1 ...

  9. 暑假训练-义乌(7.8-7.15)

    暑假训练 模拟赛 图表 数据 7.8(lxl) 7.9(lxl) 7.10(lxl) 7.11(lxl) 7.12(wls) 7.13(wls) 7.14(wls) 7.15(lfds) 训练 数据结 ...

最新文章

  1. jsp ul设置滚动条_jquery实现Li滚动时滚动条自动添加样式的方法
  2. 基于Springboot实现园区招商管理系统
  3. jQ 插件 iscroll.js
  4. 白话Elasticsearch26-深度探秘搜索技术之function_score自定义相关度分数算法
  5. 2019天梯赛(总结-无题解)
  6. Java中input与output_java中的Io(input与output)操作总结(四)
  7. Kubernetes集群上的Apache Ignite和Spring第3部分:测试应用程序
  8. linux cmake 安装mysql5.5.11_以及更高版本_linux cmake 安装mysql5.5.11,以及更高版本
  9. (附源码)APP+springboot订餐APP 毕业设计 190711
  10. 通达信波段王指标公式主图_通达信波段操作主图指标公式
  11. 如何设置三线表线条的粗细
  12. 三星a60android9,三星A6060官方港版安卓9固件rom线刷包:TGY-A6060ZHU1ASH3
  13. mysql server has gone away_mysql server has gone away的解决方法
  14. 宝利通网闸怎么设置_polycomMCU操作指南
  15. c1语言水平要多久,「西班牙留学」零基础到西班牙读语言,多久能到C1?
  16. 关于下载淘宝教育的课程
  17. Codeforces 1324D(红黑树+求指定区间中大于指定值的个数)
  18. itext实现pdf内容替换
  19. 北美CS求学找工指南
  20. 浙江省高等学校教师教育理论培训上机考试

热门文章

  1. tkinter # If this fails your Python may not be configured for Tk解决方法
  2. arduino运行java_IC之路(一)Proteus-Arduino仿真环境搭建
  3. leetcode - 136. 只出现一次的数字
  4. 去哪儿-22-async-components
  5. Canny边缘检测及C++实现(转载)
  6. CV之Harris特征点检测器-兴趣点检测(详解)
  7. 类加载器ClassLoader
  8. 最大子序列和的四种求解算法及其时间比较
  9. 路由添加失败 参数错误_路由器故障排错三大经典案例详解
  10. java 线程钩子_高级并发编程系列六(线程池钩子函数)