fzu2028
//Accepted 7324 KB 203 ms /* source:fzu2028 time :2015.5.29 by :songt */ /*题解: 树链剖分 单点更新,求路径和 */ #include <cstdio> #include <cstring> ; int max(int a,int b) { return a>b?a:b; } void swap(int &a,int &b) { int t=a; a=b; b=t; } struct Edge { int u,v; Edge(){} Edge(int u,int v):u(u),v(v){} } edge[*imax_n]; int head[imax_n]; *imax_n]; int tot; void addEdge(int u,int v) { edge[tot]=Edge(u,v); next[tot]=head[u]; head[u]=tot++; } int fa[imax_n],deep[imax_n],num[imax_n],son[imax_n]; int p[imax_n],fp[imax_n],top[imax_n]; int pos; void init() { memset(head,-,sizeof(head)); memset(next,-,sizeof(next)); tot=; memset(son,-,sizeof(son)); pos=; } void dfs1(int u,int pre,int depth) { deep[u]=depth; fa[u]=pre; num[u]=; ;i=next[i]) { int v=edge[i].v; if (v!=pre) { dfs1(v,u,depth+); num[u]+=num[v]; || num[son[u]]<num[v]) son[u]=v; } } } void dfs2(int u,int sp) { p[u]=pos++; fp[p[u]]=u; top[u]=sp; ) return ; dfs2(son[u],sp); ;i=next[i]) { int v=edge[i].v; if (v!=fa[u] && v!=son[u]) { dfs2(v,v); } } } struct Tree { int l,r; long long sum; int tmax; }f[imax_n*]; void build(int t,int l,int r) { f[t].l=l; f[t].r=r; f[t].sum=; f[t].tmax=; if (l==r) { return ; } ; build(*t,l,mid); build(*t+,mid+,r); } void update(int t,int k,int value) { if (f[t].l==k && f[t].r==k) { f[t].sum=value; f[t].tmax=value; return ; } ; *t,k,value); *t+,k,value); f[t].sum=f[*t].sum+f[*t+].sum; f[t].tmax=max(f[*t].tmax,f[*t+].tmax); } long long query(int t,int l,int r,int &tmax) { if (f[t].l==l && f[t].r==r) { tmax=f[t].tmax; return f[t].sum; } ; *t,l,r,tmax); else { *t+,l,r,tmax); else { int tmax1,tmax2; long long sum1,sum2; sum1=query(*t,l,mid,tmax1); sum2=query(*t+,mid+,r,tmax2); tmax=max(tmax1,tmax2); return sum1+sum2; } } } long long find(int u,int v,int tmax) { int f1=top[u],f2=top[v]; ; ; int t; while (f1!=f2) { if (deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); } sum+=query(,p[f1],p[u],t); tmp=max(tmp,t); u=fa[f1]; f1=top[u]; } if (u==v) return sum; if (deep[u]>deep[v]) swap(u,v); sum+=query(,p[son[u]],p[v],t); tmp=max(tmp,t); tmax=tmp; return sum; } ]; int n,m; int main() { ) { init(); ;i<n-;i++) { scanf(],&e[i][],&e[i][]); addEdge(e[i][],e[i][]); addEdge(e[i][],e[i][]); } dfs1(,,); dfs2(,); //printf("after dfs\n"); build(,,pos-); //printf("after build\n"); ;i<n-;i++) { ]]<deep[e[i][]]) swap(e[i][],e[i][]); update(,p[e[i][]],e[i][]); } //printf("after insert\n"); int kind; int u,v,c; int tmax; ;i<m;i++) { scanf("%d%d%d",&kind,&u,&v); ) { update(,p[e[u-][]],v); } else { printf("%lld\n",find(u,v,tmax)); } } } ; }
fzu2028的更多相关文章
随机推荐
- Image放大缩小在放进Imageview
// 拿到要缩小放大的Bitmap obitmap = BitmapFactory.decodeResource(this.getResources(),R.drawable.ic_launcher) ...
- AxureRP8实战手册(基础31-40)
AxureRP8实战手册(基础31-40) 本文目录 基础31. 切换元件库 第2章 页面设置 基础32. 设置页面居中 基础33. 设置页面背景(图片/颜色 ...
- HTML 的 meta 标签
我们先来看看维基百科上对 meta element 的定义: Meta elements are tags used in HTML and XHTML documents to provide st ...
- nodejs学习笔记之events
events 模块只提供了一个对象: events.EventEmitter. EventEmitter 的核心就是事件触发与事件监听器功能的封装. 可以通过require("events& ...
- 效率最高的Excel数据导入---(c#调用SSIS Package将数据库数据导入到Excel文件中【附源代码下载】) 转
效率最高的Excel数据导入---(c#调用SSIS Package将数据库数据导入到Excel文件中[附源代码下载]) 本文目录: (一)背景 (二)数据库数据导入到Excel的方法比较 ...
- JS基本概念
1.一切(变量.函数名.操作符)都区分大小写 2.标识符:第一个字符必须为字母.下划线或者美元符号,其他字符可以是字母.下划线.美元符号或者数字 3.数据类型 1)undefined:用var声明的变 ...
- for(String s:v)
s是遍历后赋值的变量,v是要遍历的list.可以通过以下语句进行测试: List<String> v=new ArrayList(); v.add("one"); v. ...
- android自动获取短信验证码
前言:android应用的自动化测试必然会涉及到注册登录功能,而许多的注册登录或修改密码功能常常需要输入短信验证码,因此有必要能够自动获得下发的短信验证码.主要就是实时获取短信信息.android上获 ...
- EntityFrameWork使用MySql数据库分页的BUG
环境 使用MySQL Connector NET 6.7.4+EF5.0+VS2010 问题描述 IQueryable<T>类型的Where方法和Skip或Take方法一起使用时,生成的S ...
- 将1~n个整数按字典顺序进行排序,返回排序后第m个元素
给定一个整数n,给定一个整数m,将1~n个整数按字典顺序进行排序,返回排序后第m个元素.n最大可为5000000.字典排序的含义为:从最高位开始比较.1开头的数字排在最前面,然后是2开头的数字,然后是 ...