FZU 2082 过路费 (树链剖分)
来源:互联网 发布:优畅网络正规吗 编辑:程序博客网 时间:2024/04/30 20:14
传送门:http://acm.fzu.edu.cn/problem.php?pid=2082
这题有个注意点,就是他更改的时候是更改第a条边,那我们怎么才能知道第a条边是更改线段树上的哪个点呢?因为我们在表示边的时候是用一个点表示他的父亲边,所以第a条边是用这条边上深度大的那个点来表示的,problem solved。
一次AC!
#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <iostream>#include <vector>#include <map>#include <set>#include <queue>#include <ctime>using namespace std;typedef long long ll;typedef pair<int,int> pii;#define pb push_back#define mp make_pair#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define calm (l+r)>>1const int INF=2139062143;const int maxn=50010;struct EE{ int to,next,val; EE(){} EE(int t,int n,int v):to(t),next(n),val(v){}}edge[maxn<<1];struct EEE{ int from,to,val; EEE(){} EEE(int f,int t,int v):from(f),to(t),val(v){}}Edge[maxn];int n,m,Ecnt,tot,head[maxn];int top[maxn],fa[maxn],id[maxn],son[maxn],num[maxn],rev[maxn],deep[maxn];int val[maxn];inline void add(int a,int b,int c){ edge[Ecnt]=EE(b,head[a],c); head[a]=Ecnt++;}void dfs(int s,int pre,int d){ fa[s]=pre;deep[s]=d;num[s]=1;son[s]=0; for(int i=head[s];~i;i=edge[i].next){ int t=edge[i].to; if(t==pre)continue; dfs(t,s,d+1);num[s]+=num[t]; if(son[s]==0||num[son[s]]<num[t]){ son[s]=t; } }}void dfs(int s,int rt){ top[s]=rt;id[s]=++tot;rev[tot]=s; if(!son[s])return; dfs(son[s],rt); for(int i=head[s];~i;i=edge[i].next){ int t=edge[i].to; if(t==fa[s]||t==son[s])continue; dfs(t,t); }}int sum[maxn<<2];inline void pushup(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(int l,int r,int rt){ sum[rt]=0; if(l==r){ sum[rt]=val[rev[l]]; return; } int m=calm; build(lson);build(rson); pushup(rt);}void update(int x,int v,int l,int r,int rt){ if(l==r){sum[rt]=v;return;} int m=calm; if(x<=m)update(x,v,lson); else update(x,v,rson); pushup(rt);}ll query(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R){ return sum[rt]; } int m=calm; ll ans=0; if(L<=m)ans+=query(L,R,lson); if(R>m)ans+=query(L,R,rson); return ans;}int getID(int x){ EEE e=Edge[x]; if(deep[e.from]>deep[e.to])return e.from; return e.to;}ll solve(int x,int y){ int f1=top[x],f2=top[y]; ll ans=0; while(f1!=f2){ if(deep[f1]<deep[f2]){ swap(f1,f2);swap(x,y); } ans+=query(id[f1],id[x],1,tot,1); x=fa[f1];f1=top[x]; } if(x!=y){ if(deep[x]>deep[y])swap(x,y); ans+=query(id[son[x]],id[y],1,tot,1); } return ans;}int main(){ //freopen("D://input.txt","r",stdin); while(scanf("%d%d",&n,&m)!=EOF){ Ecnt=0;memset(head,-1,sizeof head); for(int i=1;i<n;i++){ scanf("%d%d%d",&Edge[i].from,&Edge[i].to,&Edge[i].val); add(Edge[i].from,Edge[i].to,Edge[i].val); add(Edge[i].to,Edge[i].from,Edge[i].val); } tot=0; dfs(1,0,1);dfs(1,1); for(int i=1;i<n;i++){ int a=Edge[i].from; int b=Edge[i].to; if(deep[a]>deep[b]){ val[a]=Edge[i].val; } else{ val[b]=Edge[i].val; } } build(1,tot,1); while(m--){ int op,a,b;scanf("%d%d%d",&op,&a,&b); if(op==0){ int x=getID(a); update(id[x],b,1,tot,1); val[x]=b; } else{ printf("%I64d\n",solve(a,b)); } } } return 0;}
0 0
- FZU 2082 过路费(树链剖分)
- fzu 2082 过路费(树链剖分)
- FZU 2082 过路费 (树链剖分)
- FZU 2082 过路费(树链剖分)
- 【树链剖分】 FZU 2082 过路费
- fzu 2082 过路费(树链剖分)
- FZU 2082 过路费 (树链剖分)
- FZU 2082 过路费 树链剖分
- FZU 2082过路费 树链剖分
- FZU 2082 过路费 [树链剖分]
- FZU 2082 过路费 (树链剖分)边权
- FZU 2082 过路费(树链剖分+BIT)
- FZU 2082 过路费(树链剖分,边权)
- 【树链剖分】FZU 2082 过路费 求和
- 树链刨分 (FZU 2082过路费)
- fzu 2082 过路费(树链剖分,询问两点距离)
- fzu 2082 过路费(树链剖分,单点更新+区间求和)
- FZU 2082 过路费(树链剖分+线段树)
- Linux3操作篇-用户、文件目录、权限管理与磁盘管理
- Java 抽象类的详解
- swing组件之JScrollPane滚动条
- strlen,strcpy,strcat,strcmp函数的实现
- 网络游戏封包基础知识
- FZU 2082 过路费 (树链剖分)
- Mybatis 3.1中 Mapper XML 文件 的学习详解
- 关于Certificate、Provisioning Profile、App ID的介绍及其之间的关系
- java Reference
- WebView加载Html 乱码问题
- C++异常处理基础
- 工作周会的总结
- html空格
- coderforce #round117D (kmp)