首页 技术 正文
技术 2022年11月21日
0 收藏 459 点赞 2,219 浏览 2203 个字

  题目传送门:1036: [ZJOI2008]树的统计Count

  这道题是我第一次打树剖的板子,虽然代码有点长,但是“打起来很爽”,而且整道题只花了不到1.5h+,还是一遍过样例!一次提交AC!(难道前天膜cyc神犇真的起作用了?)

  按捺不住激动的心情!!!

  这道题是树剖+线段树模板题,树剖把树转化成线段后就可以单点修改+区间求和/区间求max了。

  又臭又长的93行代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct point{
int sum,max;
}a[];
int fir[],to[],ne[];
int vis[],fa[],dep[],size[],hson[],top[],id[];
int tot,n,m,q;
char s[];
void change(int now,int l,int r,int x,int k)
{
if(l==r)a[now].sum=a[now].max=k;
else{
int mid=(l+r)>>;
if(x<=mid)change(now<<,l,mid,x,k);else change(now<<|,mid+,r,x,k);
a[now].sum=a[now<<].sum+a[now<<|].sum; a[now].max=max(a[now<<].max,a[now<<|].max);
}
}
int getsum(int now,int l,int r,int x,int y)
{
if(x<=l&&r<=y)return a[now].sum;
else{
int mid=(l+r)>>,sum=;
if(x<=mid)sum+=getsum(now<<,l,mid,x,y);
if(mid<y)sum+=getsum(now<<|,mid+,r,x,y);
return sum;
}
}
int getmax(int now,int l,int r,int x,int y)
{
if(x<=l&&r<=y)return a[now].max;
else{
int mid=(l+r)>>,mx=-<<;
if(x<=mid)mx=max(mx,getmax(now<<,l,mid,x,y));
if(mid<y)mx=max(mx,getmax(now<<|,mid+,r,x,y));
return mx;
}
}
void add(int x,int y){to[++tot]=y; ne[tot]=fir[x]; fir[x]=tot;}
void dfs1(int now,int d)
{
int i,mxson=; size[now]=; vis[now]=; dep[now]=d;
for(i=fir[now];i;i=ne[i])
if(!vis[to[i]]){
fa[to[i]]=now; dfs1(to[i],d+);
if(size[to[i]]>mxson)mxson=size[to[i]],hson[now]=to[i];
size[now]+=size[to[i]];
}
}
void dfs2(int now,int tp)
{
int i;
top[now]=tp; id[now]=++tot;
if(hson[now])dfs2(hson[now],tp);
for(i=fir[now];i;i=ne[i])
if(to[i]!=hson[now]&&to[i]!=fa[now])dfs2(to[i],to[i]);
}
int main()
{
int i,x,y;
scanf("%d",&n); tot=;
for(i=;i<n;i++)scanf("%d%d",&x,&y),add(x,y),add(y,x);
for(i=;i<=n;i++)vis[i]=; tot=;
dfs1(,); dfs2(,);
for(i=;i<=n;i++)scanf("%d",&x),change(,,n,id[i],x);
scanf("%d",&q);
for(i=;i<=q;i++){
scanf("%s%d%d",s,&x,&y);
if(s[]=='C')change(,,n,id[x],y);
else if(s[]=='M'){
int mx=-<<;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){int tmp=x; x=y; y=tmp;}
mx=max(mx,getmax(,,n,id[top[x]],id[x])); x=fa[top[x]];
}
if(dep[x]>dep[y]){int tmp=x; x=y; y=tmp;}
printf("%d\n",max(mx,getmax(,,n,id[x],id[y])));
}
else{
int sum=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){int tmp=x; x=y; y=tmp;}
sum+=getsum(,,n,id[top[x]],id[x]); x=fa[top[x]];
}
if(dep[x]>dep[y]){int tmp=x; x=y; y=tmp;}
printf("%d\n",sum+getsum(,,n,id[x],id[y]));
}
}
}

树链剖分+线段树

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,996
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,510
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,353
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,137
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,770
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,848