树的统计count
来源:互联网 发布:删除旧的windows文件夹 编辑:程序博客网 时间:2024/05/29 13:34
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#define maxn 300000#define ls x<<1#define rs x<<1|1using namespace std;int n,head[maxn],tot=0,v[maxn],top[maxn],son[maxn],fa[maxn],de[maxn],w[maxn],z,tree1[maxn],tree2[maxn],sz[maxn];char s[20];struct eg{ int to; int nxt;}b[maxn];void link(int x,int y){ b[++tot].nxt=head[x]; b[tot].to=y; head[x]=tot;}void dfs1(int x,int f){ sz[x]=1,fa[x]=f; for (int i=head[x];i!=-1;i=b[i].nxt) { int t=b[i].to; if (t==f) continue; de[t]=de[x]+1; dfs1(t,x); sz[x]+=sz[t]; if (son[x]==-1||sz[son[x]]<sz[t]) son[x]=t; }}void dfs2(int x,int tp){ top[x]=tp,w[x]=++z; if (son[x]!=-1) dfs2(son[x],tp); else return ; for (int i=head[x];i!=-1;i=b[i].nxt) { int t=b[i].to; if (t!=fa[x]&&t!=son[x]) dfs2(t,t); }}void build(int x,int l,int r){ tree2[x]=0,tree1[x]=-900000000; if (l==r) return ; int mid=(l+r)>>1; build (ls,l,mid); build (rs,mid+1,r);}void updata(int x,int l,int r,int d,int y){ if (l==r&&l==d) { tree1[x]=y; tree2[x]=y; return ; } int mid=(l+r)>>1; if (d<=mid)updata(ls,l,mid,d,y); else updata(rs,mid+1,r,d,y); tree1[x]=max(tree1[ls],tree1[rs]); tree2[x]=tree2[ls]+tree2[rs];}int qsum(int x,int l,int r,int ll,int rr){ if (ll==l&&r==rr) return tree2[x]; int mid=(l+r)>>1; if (ll>mid) return qsum(rs,mid+1,r,ll,rr); else if (rr<=mid) return qsum(ls,l,mid,ll,rr); else return qsum(ls,l,mid,ll,mid)+qsum(rs,mid+1,r,mid+1,rr);}int qmax(int x,int l,int r,int ll,int rr){ if (ll==l&&r==rr) return tree1[x]; int mid=(l+r)>>1; if (rr<=mid) return qmax(ls,l,mid,ll,rr); else if (ll>mid) return qmax(rs,mid+1,r,ll,rr); else return max(qmax(ls,l,mid,ll,mid),qmax(rs,mid+1,r,mid+1,rr));}int find(int x,int y,int flag){ if (flag==1) { int ans=-900000000; int f1=top[x],f2=top[y]; while(f1!=f2) { if(de[f1]<de[f2]) swap(f1,f2),swap(x,y); ans=max(ans,qmax(1,1,z,w[f1],w[x])); x=fa[f1],f1=top[x]; } if (de[x]>de[y]) swap(x,y); return max(ans,qmax(1,1,z,w[x],w[y])); } if (flag==2) { int ans=0; int f1=top[x],f2=top[y]; while (f1!=f2) { if(de[f1]<de[f2]) swap(f1,f2),swap(x,y); ans+=qsum(1,1,z,w[f1],w[x]); x=fa[f1],f1=top[x]; } if (de[x]>de[y]) swap(x,y); return ans+qsum(1,1,z,w[x],w[y]); }}int main(){ memset(head, -1, sizeof(head)); memset(son, -1, sizeof(son)); scanf ("%d",&n); for (int i=1;i<n;++i) { int x,y; scanf ("%d%d",&x,&y); link(x,y); link(y,x); } for (int i=1;i<=n;++i) scanf ("%d",&v[i]); de[1]=1; dfs1(1,0); dfs2(1,1); build(1,1,z); for (int i=1;i<=n;++i) updata(1,1,z,w[i],v[i]); int q; scanf("%d",&q); for (int i=1;i<=q;++i) { scanf ("%s",s); int x,y; scanf ("%d%d",&x,&y); if (s[0]=='C') updata(1,1,z,w[x],y); if (s[1]=='M') printf("%d\n",find(x,y,1)); if (s[1]=='S') printf("%d\n",find(x,y,2)); } return 0;}
嗯我知道打得很丑然而毕竟是第一个几乎全靠自己的树剖板子吧qaq
诶嘿嘿
1 0
- 树的统计count
- [ZJOI2008]树的统计Count
- [ZJOI2008]树的统计Count
- hybz1036 树的统计Count
- BZOJ1036 树的统计Count
- bzoj1036树的统计Count
- BZOJ1036树的统计Count
- [ZJOI2008]树的统计Count
- 树的统计Count HYSBZ
- bzoj1036 树的统计Count
- HYSBZ1036-树的统计Count
- [ZJOI2008]树的统计Count
- [ZJOI2008]树的统计Count
- 树的统计Count 树剖模板
- 1036: [ZJOI2008]树的统计Count 树链剖分裸题
- [Bzoj1036][ZJOI2008]树的统计Count
- BZOJ 1036: [ZJOI2008]树的统计Count
- BZOJ1036 [ZJOI2008]树的统计Count 树链剖分
- 面试题汇总
- 链表写通讯录
- JDBC数据库连接实例分享
- Redis数据库连接类分布式版
- Redis- 对象的空转时长(总结)
- 树的统计count
- CentOS7 安装Node.js
- GRE-C
- 基于Netty3的RPC架构笔记2之服务端与客户端
- HDU 1597 二分+数学
- javaSE的几个基本问题
- CentOS里上传下载rzsz
- ThinkPhP 学习笔记 1.介绍及安装
- TensorFlow手写数字识别mnist example源码分析