题目大意:

有一棵有根树,根为 1 ,点有点权。
现在有 m 次操作,操作有 3 种:
1 x y w ,将 x 到 y 的路径上的点点权加上 w (其中 w=±1w=±1 );
2 x y ,询问在 x 到 y 的路径上有多少个点点权 >0 ;
3 x ,询问在 x 的子树里的点有多少个点点权 >0 。

数据范围:$n,m≤10^5$,点权的绝对值$≤10^9$。

这一题正常的做法并不是特别优秀,我们考虑一些分块做法

考虑求一个连续的区间内有多少个数$>0$,我们显然可以将原序列分成$\sqrt{n}$块,对于每一个块我们开一个桶存储块内所有数,然后类似前缀和的方式扫一遍,查询一个块就可以$O(1)$实现查询了

修改怎么做?

首先是整个块一起变大/变小的情况,我们对整一块打一个标记$tag[x]$,下次查询时不要查询$>0$的,改为查询块内$>tag[x]$的数的数量。

某个块更改一部分的情况:我们修改原数,然后直接更改该块对应的桶即可,详见代码。

这个做法既然可以针对某一个区间,且资瓷修改。

回到原先的问题中,我们对给出的树树剖一下,每条链我们都分块维护一下,在此不再赘述。

查询某条路径的话,我们将询问拆成$\log{n}$条链,分别查询然后加起来即可。

查询某个子树内的话,直接查就可以了。

时间复杂度:$O(n^{1.5}\log\ n)$,代码只要3k。

别想什么树分块!!!

 #include<bits/stdc++.h>
#define L long long
#define M 100005
#define N 500
using namespace std; int B[M]={},S[M]={},tag[M]={},E[M]={},pos[M]={},a[M]={};short num[M/N+][M*]={};
void upd(short x[],int &y,int Val){if(Val==) ++x[++y+];else --x[y--+];}
void updata(int l,int r,int w){
if(B[l]==B[r]){for(int i=l;i<=r;i++) upd(num[B[i]],a[i],w); return;}
for(int i=l;B[i]==B[l];i++) upd(num[B[i]],a[i],w);
for(int i=r;B[i]==B[r];i--) upd(num[B[i]],a[i],w);
for(int i=B[l]+;i<B[r];i++) tag[i]+=w;
}
L query(int l,int r){
L res=;
if(B[l]==B[r]){for(int i=l;i<=r;i++) res+=(a[i]+tag[B[i]]>); return res;}
for(int i=l;B[i]==B[l];i++) res+=(a[i]+tag[B[i]]>);
for(int i=r;B[i]==B[r];i--) res+=(a[i]+tag[B[i]]>);
for(int i=B[l]+;i<B[r];i++) res+=num[i][-tag[i]];
return res;
} struct edge{int u,next;}e[M*]={}; int head[M]={},use=;
void add(int x,int y){use++;e[use].u=y;e[use].next=head[x];head[x]=use;}
int siz[M]={},son[M]={},dep[M]={},fa[M]={},dfn[M]={},low[M]={},top[M]={},t=;
void dfs(int x){
siz[x]=; dep[x]=dep[fa[x]]+;
for(int i=head[x];i;i=e[i].next) if(e[i].u!=fa[x]){
fa[e[i].u]=x; dfs(e[i].u);
siz[x]+=siz[e[i].u];
if(siz[son[x]]<siz[e[i].u]) son[x]=e[i].u;
}
}
void dfs(int x,int Top){
top[x]=Top; dfn[x]=++t;
if(son[x]) dfs(son[x],Top);
for(int i=head[x];i;i=e[i].next) if(e[i].u!=fa[x]&&e[i].u!=son[x]) dfs(e[i].u,e[i].u);
low[x]=t;
} L Query(int x,int y){
L res=;
for(;top[x]!=top[y];x=fa[top[x]]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res+=query(dfn[top[x]],dfn[x]);
}
res+=query(min(dfn[x],dfn[y]),max(dfn[x],dfn[y]));
return res;
}
void Updata(int x,int y,int w){
for(;top[x]!=top[y];x=fa[top[x]]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
updata(dfn[top[x]],dfn[x],w);
}
updata(min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),w);
} #define MFLONG 18000000
#define NUM(x) ((48<=x&&x<=57)||x=='-')
char _c[MFLONG];int _ns=,_nw=;int _x[],_ld;
inline void rd(int &_q){int _fu;if(_c[_ns]==) return;while(!NUM(_c[_ns])) _ns++;if(_c[_ns]=='-') _fu=-,_ns++;else _fu=;_q=;while(NUM(_c[_ns])) _q=_q*+_c[_ns++]-;_q=_fu*_q;} int n,m,T,ans=;
int main(){
fread(_c,,MFLONG,stdin);
memset(S,,sizeof(S));
rd(n); rd(m); rd(T);
for(int i=;i<=n;i++){
B[i]=i/N+;
S[B[i]]=min(S[B[i]],i);
E[B[i]]=max(E[B[i]],i);
}
for(int i=,x,y;i<n;i++) rd(x),rd(y),add(x,y),add(y,x);
dfs(); dfs(,);
for(int i=;i<=n;i++){
rd(a[dfn[i]]);
if(a[dfn[i]]>1e5) a[dfn[i]]=1e5;
if(a[dfn[i]]<-1e5) a[dfn[i]]=-1e5;
}
for(int x=;x<=B[n];x++){
for(int i=S[x];i<=E[x];i++) ++num[x][a[i]+];
for(int j=;~j;j--) num[x][j]+=num[x][j+];
}
while(m--){
int op,x,y,w; rd(op); rd(x); x^=T*ans;
if(op==) {printf("%lld\n",ans=query(dfn[x],low[x])); continue;}
rd(y); y^=T*ans;
if(op==) {printf("%lld\n",ans=Query(x,y)); continue;}
rd(w); Updata(x,y,w);
}
}

【UOJ#435】【集训队作业2018】Simple Tree 分块+树链剖分的更多相关文章

  1. [集训队作业2018]蜀道难——TopTree+贪心+树链剖分+链分治+树形DP

    题目链接: [集训队作业2018]蜀道难 题目大意:给出一棵$n$个节点的树,要求给每个点赋一个$1\sim n$之内的权值使所有点的权值是$1\sim n$的一个排列,定义一条边的权值为两端点权值差 ...

  2. Codeforces Round #329 (Div. 2) D. Happy Tree Party 树链剖分

    D. Happy Tree Party Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/593/p ...

  3. 【POJ3237】Tree(树链剖分)

    题意:在一棵N个节点,有边权的树上维护以下操作: 1:单边修改,将第X条边的边权修改成Y 2:区间取反,将点X与Y在树上路径中的所有边边权取反 3:区间询问最大值,询问X到Y树上路径中边权最大值 n& ...

  4. HDU 4718 The LCIS on the Tree(树链剖分)

    Problem Description For a sequence S1, S2, ... , SN, and a pair of integers (i, j), if 1 <= i < ...

  5. POJ 3237:Tree(树链剖分)

    http://poj.org/problem?id=3237 题意:树链剖分.操作有三种:改变一条边的边权,将 a 到 b 的每条边的边权都翻转(即 w[i] = -w[i]),询问 a 到 b 的最 ...

  6. QTREE3 spoj 2798. Query on a tree again! 树链剖分+线段树

    Query on a tree again! 给出一棵树,树节点的颜色初始时为白色,有两种操作: 0.把节点x的颜色置反(黑变白,白变黑). 1.询问节点1到节点x的路径上第一个黑色节点的编号. 分析 ...

  7. spoj 375 Query on a tree(树链剖分,线段树)

      Query on a tree Time Limit: 851MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Sub ...

  8. bzoj 3637: Query on a tree VI 树链剖分 && AC600

    3637: Query on a tree VI Time Limit: 8 Sec  Memory Limit: 1024 MBSubmit: 206  Solved: 38[Submit][Sta ...

  9. poj 3237 Tree(树链剖分,线段树)

    Tree Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 7268   Accepted: 1969 Description ...

随机推荐

  1. 使用reactjs做一个CRUD功能

    第一步:引入reactjs所依赖的js文件,本案例使用的是bootstrap前端框架,所以引入了相应的js和css文件 第二步:body里面添加两个div 第三步:开始编写reactjs脚本 < ...

  2. 机器学习 数据预处理之独热编码(One-Hot Encoding)

    问题由来 在很多机器学习任务中,特征并不总是连续值,而有可能是分类值. 例如,考虑一下的三个特征: ["male", "female"] ["from ...

  3. DIV+CSS实战(五)

    一.说明 前面实现了关键词订阅模块,现在实现站点订阅模块,主要实现的是站点添加界面.站点添加界面里面实现一个提示框不在提示的功能(保存到cookie中),还有就是实现一个站点的选择框,包括输入文字自动 ...

  4. iOS中清除缓存的方法 以及SDWebimage自带的清除缓存方法

    1  SDWebimage中 (1)  计算缓存的大小 单位 : (MB) CGFloat size = [[SDImageCache sharedImageCache] getSize] / 102 ...

  5. 第二届普适计算和信号处理及应用国际会议论文2016年 The 2nd Conference on Pervasive Computing, Signal Processing and Applications(PCSPA, 2016)

    A New Method for Mutual Coupling Correction of Array Output Signal 一种阵列输出信号互耦校正的新方法 Research of Robu ...

  6. Linux 系统中进程5中常见状态

    运行.中断.不可终端.僵死.停止 R(运行):正在运行 or 在运行队列中等待: S(中断):处于休眠中,等待接收信号,并脱离改状态: D(不可中断):不响应信号输入,即使kill也不起作用: Z(僵 ...

  7. python 的几种启动方式

    python 的几种启动方式 (1)利用Win的操作系统的:命令行工具 cmd.exe Win + R  调出运行对话框,然后输入cmd,即可调出“命令提示符对话框” 或者 在菜单中店家附件中的命令提 ...

  8. springmvc 开涛 数据验证

    两种方式:编程和声明. 编程需要:验证器,控制器,servlet.xml,错误码设置 声明需要:加jar包,控制器,跟孔浩讲得类似 错误消息设置的两种方式:硬编码:从资源文件中读取(默认,自定义).

  9. 移动端与PC端的viewport

    第一种解析: 设备像素,就是我们直觉上觉得"靠谱"的像素,这些像素为所使用的各种设备提供了正规的分辨率,并且其值可以通过(通常情况下)从screen.width/height属性中 ...

  10. 使用Postman验证TFS Rest API

    概述 你可能已经了解到,TFS自2015版本发布以来,开始支持通过REST API的方式提供接口服务,第三方平台可以通过通用的HTTP协议访问TFS系统,获取数据.请求编译等.REST API在原有. ...