搞了一晚上,错了,以后回头再来看

/*
对于每次更新,先处理其儿子方向,再处理其父亲方向
处理父亲方向时无法达到根,那么直接更新
如果能达到根,那么到兄弟链中去更新,使用bfs序
最后,查询结点v的结果就是dfs序线段树上的查询值+bfs线段树上的查询值
*/
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
#define maxn 150005
int n,q;
vector<int> mp[maxn]; struct node{
int u,depth;
}now,nex;
int depthL[maxn];//深度为i的下标最小的点
int depthR[maxn];//深度为i的下标最大的点
int num[maxn];//bfs序
int vis[maxn]; int L[maxn];//dfs入序
int R[maxn];//某结点为根的最大深度
int dist[maxn];
int cnt;
void Dfs(int u,int from,int dis){
L[u]=++cnt;
dist[u]=dis;
for(int i=;i<mp[u].size();i++){
int v=mp[u][i];
if(v==from) continue;
Dfs(v,u,dis+);
}
R[u]=cnt;
}
//处理bfs序的方法
void Bfs(){
int tot=;
queue<node>s;
now.u=,now.depth=;
s.push(now);
memset(depthL,-,sizeof depthL);
memset(depthR,,sizeof depthR);
memset(vis,,sizeof vis);
vis[]=;
while(!s.empty()){
tot++;
now=s.front();
s.pop();
num[now.u]=tot;
if(depthL[now.depth==-])
depthL[now.depth]=num[now.u];
depthR[now.depth]=max(depthR[now.depth],num[now.u]);
for(int i=;i<mp[now.u].size();i++){
int v=mp[now.u][i];
if(vis[v]==){
vis[v]=;
nex.u=v;
nex.depth=now.depth+;
s.push(nex);
}
}
}
}
//第一棵线段树处理dfs上的修改和查询,因为所有的子树都是链,其dfs连续,所以直接用线段树区间更新
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int tree[maxn<<];
int flag[maxn<<];
inline void pushup(int rt){
tree[rt]=tree[rt<<]+tree[rt<<|];
}
inline void pushdown(int l,int r,int rt){
if(flag[rt]){
int m=l+r>>;
flag[rt<<]+=flag[rt];
tree[rt<<]=(m-l+)*flag[rt];
tree[rt<<|]=(r-m)*flag[rt];
flag[rt]=;
}
}
void build(int l,int r,int rt){
tree[rt]=flag[rt]=;
if(l==r) return;
int m=l+r>>;
pushdown(l,r,rt);
build(lson);
build(rson);
pushup(rt);
}
void update(int L,int R,int c,int l,int r,int rt){
if(L<=l && R>=r){
tree[rt]+=(r-l+)*c;
flag[rt]+=c;
return;
}
int m=l+r>>;
pushdown(l,r,rt);
if(L<=m) update(L,R,c,lson);
if(R>m) update(L,R,c,rson);
pushup(rt);
}
//是单点查询
int query(int p,int l,int r,int rt){
if(l==r) return tree[rt];
int m=l+r>>;
pushdown(l,r,rt);
if(p<=m) return query(p,lson);
if(p>m) return query(p,rson);
pushup(rt);
} //第二棵线段树用来处理bfs上的修改和查询
//bfs序线段树也是通过访问顺序维护信息
int sum[maxn<<];
int flag2[maxn<<];
inline void pushup2(int rt){
sum[rt]=sum[rt<<]+sum[rt<<|];
}
inline void pushdown2(int l,int r,int rt){
if(flag2[rt]){
int m=l+r>>;
flag2[rt>>]+=flag2[rt];
flag2[rt>>|]+=flag2[rt];
sum[rt>>]+=(m-l+)*flag2[rt];
sum[rt>>|]+=(r-m)*flag2[rt];
flag2[rt]=;
}
}
void build2(int l,int r,int rt){
sum[rt]=flag2[rt]=;
if(l==r) return;
int m=l+r>>;
pushdown2(l,r,rt);
build(lson);
build(rson);
pushup2(rt);
}
void update2(int L,int R,int c,int l,int r,int rt){
if(L<=l && R>=r){
sum[rt]+=(r-l+)*c;
flag2[rt]+=c;
return;
}
int m=l+r>>;
pushdown2(l,r,rt);
if(L<=m) update(L,R,c,lson);
if(R>m) update(L,R,c,rson);
pushup2(rt);
}
int query2(int p,int l,int r,int rt){
if(l==r) return sum[rt];
int m=l+r>>;
pushdown2(l,r,rt);
if(p<=m) return query2(p,lson);
if(p>m) return query2(p,rson);
pushup2(rt);
} int main(){
while(scanf("%d%d",&n,&q)==){
for(int i=;i<=n;i++)
mp[i].clear();
for(int i=;i<=n-;i++){
int x,y;
scanf("%d%d",&x,&y);
mp[x].push_back(y);
mp[y].push_back(x);
}
cnt=;
Dfs(,-,);
Bfs();
build(,n,);
build2(,n,);
while(q--){
int op;
scanf("%d",op);
if(op==){//查询结点x的值
int x;
scanf("%d",&x);
printf("%d\n",query(L[x],,n,)+query2(num[x],,n,));
}
else {
int u,v,d;scanf("%d%d%d",&u,&v,&d);
if(u==){//如果是根结点,直接在兄弟结点上更新
if(depthR[d]!=)//这个深度是有节点的
update2(,depthR[d],v,,n,);
else //这个深度没有结点了,整棵树更新
update2(,n,v,,n,);
continue;
}
//如果不是根结点上更新
//先在dfs序上更新,注意
update(L[u],min(L[u]+d,R[u]),v,,n,);
if(d<dist[u])//如果根到u距离大于d,直接在链上更新
update(L[u]-d,L[u]-,v,,n,);
else {
//先从根维护到u的父亲
update(L[u]-(dist[u]-),L[u]-,v,,n,);
update(L[u]-(dist[u]-),min(L[u]-(dist[u]-)+(d-dist[u]-),R[u]),-v,,n,);//取消root到其兄弟结点相同深度的相应修改,因为接下去bfs序修改会重复
if(depthR[d-dist[u]]!=)//如果这个深度有结点
update2(,depthR[d-dist[u]],v,,n,);
else
update2(,n,v,,n,);
}
}
}
}
}

cf276E 两棵线段树分别维护dfs序和bfs序,好题回头再做的更多相关文章

  1. hdu 5861 Road 两棵线段树

    传送门:hdu 5861 Road 题意: 水平线上n个村子间有 n-1 条路. 每条路开放一天的价格为 Wi 有 m 天的操作,每天需要用到村子 Ai~Bi 间的道路 每条路只能开放或关闭一次. ( ...

  2. BZOJ 3779 重组病毒 LCT+线段树(维护DFS序)

    原题干(由于是权限题我就直接砸出原题干了,要看题意概述的话在下面): Description 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力 ...

  3. CodeForces 587 E.Duff as a Queen 线段树动态维护区间线性基

    https://codeforces.com/contest/587/problem/E 一个序列, 1区间异或操作 2查询区间子集异或种类数 题解 解题思路大同小异,都是利用异或的性质进行转化,st ...

  4. Codeforces J. A Simple Task(多棵线段树)

    题目描述: Description This task is very simple. Given a string S of length n and q queries each query is ...

  5. UVA - 12424 Answering Queries on a Tree(十棵线段树的树链剖分)

    You are given a tree with N nodes. The tree nodes are numbered from 1 to N and have colors C1, C2,. ...

  6. 【bzoj3533】[Sdoi2014]向量集 线段树+STL-vector维护凸包

    题目描述 维护一个向量集合,在线支持以下操作:"A x y (|x|,|y| < =10^8)":加入向量(x,y);"Q x y l r (|x|,|y| < ...

  7. hdu 1556 Color the ball(线段树区间维护+单点求值)

    传送门:Color the ball Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/3276 ...

  8. CodeForces - 960F Pathwalks —— 主席树(n棵线段树)

    题目链接:https://vjudge.net/problem/CodeForces-960F You are given a directed graph with n nodes and m ed ...

  9. 笔试算法题(27):判断单向链表是否有环并找出环入口节点 & 判断两棵二元树是否相等

    出题:判断一个单向链表是否有环,如果有环则找到环入口节点: 分析: 第一个问题:使用快慢指针(fast指针一次走两步,slow指针一次走一步,并判断是否到达NULL,如果fast==slow成立,则说 ...

随机推荐

  1. git log 查看提交记录,参数:

    git log 查看提交记录,参数:-n (n是一个正整数),查看最近n次的提交信息 $ git log -2 查看最近2次的提交历史记录 -- fileName fileName为任意文件名,查看指 ...

  2. selenium_采集药品数据1_采集第一页表格

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...

  3. Swift真机调试时报错dyld: Library not loaded: @rpath/libswiftCore.dylib

    dyld: Library not loaded: @rpath/libswiftCore.dylib Referenced from: /private/var/mobile/Containers/ ...

  4. ELF文件解析(二):ELF header详解

    上一篇讲了ELF文件的总体布局,以及section和segment的概念.按照计划,今天继续讲 ELF header. 讲新的内容之前,先更正一个错误:上一篇中讲section header tabl ...

  5. Nginx Server 配置

    http { include mime.types; // 主模块:实现对配置文件包含的文件设定,可以减少主配置文件的复杂度: default_type application/octet-strea ...

  6. Storm 集群

    Apache Storm Storm是一个分布式的,可靠的,容错的数据流处理系统.Storm集群的输入流由一个被称作spout的组件管理,spout把数据传递给bolt,bolt要么把数据保存到某种存 ...

  7. Python数据分析学习目录

    python数据分析学习目录 Anaconda的安装和更新 矩阵NumPy pandas数据表 matplotlib-2D绘图库学习目录                      

  8. 整数数字调节框QSpinBox

    样式: import sys from PyQt5.QtWidgets import QApplication, QWidget, QSpinBox, QDoubleSpinBox, QHBoxLay ...

  9. 2017CCPC秦皇岛 L题One-Dimensional Maze&&ZOJ3992【模拟】

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3992 题意: 走迷宫,一个一维字符串迷宫,由'L'.'R'组成,分别 ...

  10. MySQL5.7主从复制配置

    1 my.cnf文件 配置 binlog_format = ROW log_bin_trust_function_creators=1 log-error = /usr/local/mysql/dat ...