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的更多相关文章
随机推荐
- Android 开发如何选择轮子(转)
一个项目的开发,我们不可能一切从0做起,如果真是这样,那同样要哭瞎.因此,善于借用已经做好的 "车轮" 非常重要,如: 网络访问框架:OKHttp.retrofit.android ...
- SSIS-包调用包错误的解决方案
1.错误信息: 无法解密受保护的 XML 节点“ DTS:Password”,错误为 0x8009000B“该项不适于在指定状态下使用.”.可能您无权访问此信息.当发生加密错误时会出现此错误.请确保提 ...
- Table的行列合并
<table border="1" width="200" height="200"> <tr> <td ro ...
- SPSS数据分析—判别分析
判别分析作为一种多元分析技术应用相当广泛,和其他多元分析技术不同,判别分析并没有将降维作为主要任务,而是通过建立判别函数来概括各维度之间的差异,并且根据这个判别函数,将新加入的未知类别的样本进行归类, ...
- CSS3--transform
transform:向元素应用2D或3D转换,该属性允许我们对属性旋转,缩放,移动,或倾斜. transfrom:none:定义不进行转换 transfrom:matrix(n,n,n,n,n,n); ...
- [python] 常用正则表达式爬取网页信息及分析HTML标签总结【转】
[python] 常用正则表达式爬取网页信息及分析HTML标签总结 转http://blog.csdn.net/Eastmount/article/details/51082253 标签: pytho ...
- 实现标记datagridview标题并导出Excel的功能
最近在学习winform,国庆前被布置了一个小任务,好不容易大致做出来了,决定记录下来,以此加深印象. 先说下需求:这是一个导入话单标记后并导出的功能 1. 选择excel文件 2. 定义字段 日 ...
- table中的td内容超出隐藏
<table style="table-layout: fixed;width: XXX px"> <tr> <td style="whit ...
- 中文Locale
sudo apt-get install locales dpkg-reconfigure locales 查看当前已安装locale: locale -a 查看locale设置: locale
- Python:函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 定义和调用 >>> def add(x,y): ... print('x=',x) #Python3必须加&quo ...