P1001 A+B Problem (树链剖分)
这题考验我们构造模型的能力。
考虑构造一棵树,树上有3个节点,节点1和节点2连一条权值为a的边,节点1和节点3连一条权值为b的边,显然答案就是节点2到节点3的最短路径。
但这样还不够。考虑加法的性质,我们每次给节点1和节点2,节点1和节点3的连边随机加上一个数k,节点2到节点3的最短路径上所有边减去这个数k,显然答案不变。
因为要更新和查询链的信息,写个树链剖分搞搞就行了。
上代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN=100002;
inline int gi(){
int x=0,o=1;
char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')ch=getchar(),o=-1;
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*o;
}
struct edge{
int to,w,next;
}e[MAXN<<1];
struct tree{
int val,add;
}t[MAXN<<4];
int tot=0,head[MAXN];
void add(int u,int v,int w){
e[++tot].to=v;e[tot].w=w;e[tot].next=head[u];head[u]=tot;
e[++tot].to=u;e[tot].w=w;e[tot].next=head[v];head[v]=tot;
}
int a,b,cnt=0,son[MAXN],fa[MAXN],siz[MAXN],dep[MAXN],top[MAXN],id[MAXN],d[MAXN<<1][3];
void DFS1(int u,int f,int d){
son[u]=0;fa[u]=f;siz[u]=1;dep[u]=d;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==f)continue;
DFS1(v,u,d+1);
siz[u]+=siz[v];
if(siz[son[u]]<siz[v])son[u]=v;
}
}
void DFS2(int u,int tp){
top[u]=tp;id[u]=++cnt;
if(son[u])DFS2(son[u],tp);
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==fa[u]||v==son[u])continue;
DFS2(v,v);
}
}
void pushdown(int rt,int l,int r){
int mid=(l+r)>>1;
t[rt<<1].add+=t[rt].add;
t[rt<<1|1].add+=t[rt].add;
t[rt<<1].val+=(mid-l+1)*t[rt].add;
t[rt<<1|1].val+=(r-mid)*t[rt].add;
t[rt].add=0;
}
void update(int rt,int l,int r,int ul,int ur,int add){
if(ul>r||ur<l)return;
if(ul<=l&&ur>=r){
t[rt].add+=add;
t[rt].val+=(r-l+1)*add;
return;
}
if(t[rt].add)pushdown(rt,l,r);
int mid=(l+r)>>1;
update(rt<<1,l,mid,ul,ur,add);
update(rt<<1|1,mid+1,r,ul,ur,add);
t[rt].val=t[rt<<1].val+t[rt<<1|1].val;
}
int query(int rt,int l,int r,int ql,int qr){
if(ql>r||qr<l)return 0;
if(ql<=l&&qr>=r)return t[rt].val;
if(t[rt].add)pushdown(rt,l,r);
int mid=(l+r)>>1;
return query(rt<<1,l,mid,ql,qr)+query(rt<<1|1,mid+1,r,ql,qr);
}
int ask(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=query(1,1,cnt,id[top[x]],id[x]);
x=fa[top[x]];
}
if(x==y)return ans;
if(dep[x]>dep[y])swap(x,y);
ans+=query(1,1,cnt,id[son[x]],id[y]);
return ans;
}
void add_path(int x,int y,int k){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
update(1,1,cnt,id[top[x]],id[x],k);
x=fa[top[x]];
}
if(x==y)return;
if(dep[x]>dep[y])swap(x,y);
update(1,1,cnt,id[son[x]],id[y],k);
return;
}
int main(){
a=gi();b=gi();
add(1,2,a);
add(1,3,b);
d[1][0]=1;d[1][1]=2;d[1][2]=a;
d[2][0]=1;d[2][1]=3;d[2][2]=b;
DFS1(1,0,1);
DFS2(1,1);
for(int i=1;i<3;i++){
if(dep[d[i][0]]>dep[d[i][1]])swap(d[i][0],d[i][1]);
update(1,1,cnt,id[d[i][1]],id[d[i][1]],d[i][2]);
}
for(int i=1;i<=1000000;i++){
int k=rand()%2666;
add_path(1,2,k);
add_path(1,3,k);
add_path(2,3,-k);
}
cout<<ask(2,3);
return 0;
}
1 AC 132ms/2085kB
2 AC 132ms/2015kB
3 AC 132ms/1960kB
4 AC 132ms/1960kB
5 AC 132ms/1917kB
怎么样?是不是很快啊!拿下全站rank1不是梦!
(PS:当然,解法不止上面这一种,下面是正解:)
#include<bits/stdc++.h>
using namespace std;
int main(){
scanf("%d%d",new int,new int);
printf("%d",*(new int-8)+*(new int-24));
return 0;
}
P1001 A+B Problem (树链剖分)的更多相关文章
- FZOJ 2176 easy problem ( 树链剖分 )
pid=2176" target="_blank">题目链接~~> 做题感悟:感觉做多了树链剖分的题目,有很多是树链剖分 + 想法.. 解题思路: 这题非常明 ...
- HDU 5293 Train chain Problem - 树链剖分(树状数组) + 线段树+ 树型dp
传送门 题目大意: 一颗n个点的树,给出m条链,第i条链的权值是\(w_i\),可以选择若干条不相交的链,求最大权值和. 题目分析: 树型dp: dp[u][0]表示不经过u节点,其子树的最优值,dp ...
- FZU2176---easy problem (树链剖分)
http://acm.fzu.edu.cn/problem.php?pid=2176 Problem 2176 easy problem Accept: 9 Submit: 32Time Lim ...
- (中等) HDU 5293 Tree chain problem,树链剖分+树形DP。
Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There are ...
- Codeforces Round #425 (Div. 2) Problem D Misha, Grisha and Underground (Codeforces 832D) - 树链剖分 - 树状数组
Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations ...
- HDU 4729 An Easy Problem for Elfness(树链剖分边权+二分)
题意 链接:https://cn.vjudge.net/problem/HDU-4729 给你n个点,然你求两个点s和t之间的最大流.而且你有一定的钱k,可以进行两种操作 1.在任意连个点之间建立一个 ...
- [HDU 5293]Tree chain problem(树形dp+树链剖分)
[HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...
- USACO 2015 December Contest, Platinum Problem Max Flow【树链剖分】
题意比较难理解,就是给你n个点的树,然后给你m个修改操作,每一次修改包括一个点对(x, y),意味着将x到y所有的点权值加一,最后问你整个树上的点权最大是多少. 比较裸的树链剖分了,感谢Haild的讲 ...
- 【bzoj4999】This Problem Is Too Simple! 树链剖分+动态开点线段树
题目描述 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x<2^31) ...
随机推荐
- redis集群部署及常用的操作命令(下)
搭建好集群之后,为了扩容需要再加入一个节点.那就再复制一个7006,改为相应的redis.conf(复制了改个port就好,如果复制的redis之前属于集群,需要把关联的node.conf之类的去掉) ...
- U盘安装RedHat linux 5.3
U盘安装RedHat linux 5.3 1.下载rhel-5.3-server-i386-dvd.iso文件: 2.下载绿色版UltraISO软件: 3.将rhel-5.3-server-i386- ...
- kcp流模式与消息模式对比
kcp的流模式,和消息模式 流模式: 更高的网络利用率 更大的传输速度 解析数据相对更复杂 消息模式: 更小的网络利用率 更小的传输速度 解析数据相对更简单 消息模式的示意图 http://www.p ...
- Java概述、环境变量、注释、关键字、标识符、常量
Java语言的特点 有很多小特点,重点有两个开源,跨平台 Java语言是跨平台的 Java语言的平台 JavaSE JavaME--Android ...
- hibernate3的配置
原创 链接:https://pan.baidu.com/s/1S-x271CT3wBqQodfFI1dZg 密码:ghti hiberdate3的下载链接如上 hibernate3在MyEclipse ...
- Delphi iOS & macOS App 名称支持国际化多语显示
作用:在 OSX 图标下方显示 App 中文繁体或简体的名称(系统自动选取) 适用:XE7, XE8 for OSX 操作: 创建一个新工程. 在工程目录下创建二个文件夹(zh_??.lproj)文件 ...
- 不用SQL给打印记录编号
以QUICKREPORT为例 页面设置如下: 其中ID为编号. 设置为表的ID字段. QUICKREPORT所在的FORM添加一个变量: var FprnT6: TFprnT6; Vxh:intege ...
- scvmm2008 错误 2941 0x80072efe
该错误是由于vmm和主机之间的证书不匹配所导致的. 1. 运行mmc,文件=>添加管理单元=>添加证书=>计算机账户=>本地计算机. 2. 在下图各个目录证书下删除和vmm关联 ...
- 单例模式和HttpContext线程内唯一
单例模式 --> 多个用户会使用同一个EF,且这个EF一直不能释放,EF追踪的数据越来越多,服务器内存迟早爆炸(联想应用程序池,用户可能会用到被人用过的Application,里面的EF也是被用 ...
- pageadmin网站制作 如何修改和管理网站模板
在使用pageadmin CMS 的同时,遇到问题可以参考官网帮助中心.1.网站模板目录地址/templates目录, 2.点击展开后,每个目录就是一个网站模板, 前端设计师制作的新版本都可以放到这个 ...