FZU 2082(过路费)

Posted Kurokey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FZU 2082(过路费)相关的知识,希望对你有一定的参考价值。

题目链接:传送门

题目大意:中文题,略

题目思路:树链剖分(注意要把边上的权值转移到深度较大的点上来维护)

          最后当top[x]==top[y]注意id[x]+1因为是维护的点而题目是边

          如果不+可能会出现重复加的情况。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <cstring>
  7 #include <stack>
  8 #include <cctype>
  9 #include <queue>
 10 #include <string>
 11 #include <vector>
 12 #include <set>
 13 #include <map>
 14 #include <climits>
 15 #define lson rt<<1,l,mid
 16 #define rson rt<<1|1,mid+1,r
 17 #define fi first
 18 #define se second
 19 #define ping(x,y) ((x-y)*(x-y))
 20 #define mst(x,y) memset(x,y,sizeof(x))
 21 #define mcp(x,y) memcpy(x,y,sizeof(y))
 22 using namespace std;
 23 #define gamma 0.5772156649015328606065120
 24 #define MOD 1000000007
 25 #define inf 0x3f3f3f3f
 26 #define N 50005
 27 #define maxn 30010
 28 typedef pair<int,int> PII;
 29 typedef long long LL;
 30 LL read(){
 31     LL x=0,f=1;char ch=getchar();
 32     while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
 33     while(ch>=0&&ch<=9){x=(x<<3)+(x<<1)+ch-0;ch=getchar();}
 34     return x*f;
 35 }
 36 int head[N],hcnt;
 37 int n,m,flag,L,R;
 38 int son[N],siz[N],fa[N],top[N];
 39 int id[N],tid,dep[N],posi[N];
 40 LL seg[N<<2];
 41 struct Node{int to,nxt;LL v;}node[N<<1];
 42 struct Edge{int x,y;LL v;}edge[N];
 43 void dfs1(int u,int f,int deep){
 44     fa[u]=f,dep[u]=deep,siz[u]=1;
 45     for(int i=head[u];~i;i=node[i].nxt){
 46         int e=node[i].to;if(e==f)continue;
 47         dfs1(e,u,deep+1);siz[u]+=siz[e];
 48         if(!son[u]||siz[son[u]]<siz[e])son[u]=e;
 49     }
 50 }
 51 void dfs2(int u,int tp){
 52     top[u]=tp,id[u]=++tid,posi[tid]=u;
 53     if(!son[u])return;dfs2(son[u],tp);
 54     for(int i=head[u];~i;i=node[i].nxt){
 55         int e=node[i].to;
 56         if(!id[e])dfs2(e,e);
 57     }
 58 }
 59 LL query(int rt,int l,int r){
 60     if(L<=l&&r<=R)return seg[rt];
 61     int mid=l+r>>1;LL temp=0;
 62     if(L<=mid)temp+=query(lson);
 63     if(R>mid) temp+=query(rson);
 64     return temp;
 65 }
 66 void update(int rt,int l,int r,LL v){
 67     if(l==r){seg[rt]=v;return;}
 68     int mid=l+r>>1;
 69     if(L<=mid)update(lson,v);
 70     else update(rson,v);
 71     seg[rt]=seg[rt<<1]+seg[rt<<1|1];
 72 }
 73 void lca(int x,int y){
 74     LL res=0;
 75     while(top[x]!=top[y]){
 76         if(dep[top[x]]<dep[top[y]])swap(x,y);
 77         L=id[top[x]],R=id[x];
 78         res+=query(1,1,n);
 79         x=fa[top[x]];
 80     }
 81     if(dep[x]<dep[y])swap(x,y);
 82     L=id[y]+1,R=id[x];   ///注意L +1
 83     if(x!=y)res+=query(1,1,n);
 84     printf("%lld\n",res);
 85 }
 86 void init(){
 87     mst(head,-1);hcnt=tid=0;
 88     mst(siz,0);mst(son,0);mst(id,0);
 89 }
 90 int main(){
 91     int i,j,group,x,y,v,Case=0;
 92     while(scanf("%d%d",&n,&m)!=EOF){
 93         init();
 94         for(i=1;i<n;++i){
 95             x=read(),y=read(),v=read();
 96             edge[i].x=x,edge[i].y=y,edge[i].v=v;
 97             node[hcnt].v=v,node[hcnt].to=y,node[hcnt].nxt=head[x],head[x]=hcnt++;
 98             node[hcnt].v=v,node[hcnt].to=x,node[hcnt].nxt=head[y],head[y]=hcnt++;
 99         }
100         dfs1(1,1,1);dfs2(1,1);
101         for(i=1;i<n;++i){
102             if(dep[edge[i].x]<dep[edge[i].y])swap(edge[i].x,edge[i].y);
103             L=id[edge[i].x];
104             update(1,1,n,edge[i].v);
105         }
106         while(m--){
107             x=read();
108             if(x==0){
109                 x=read(),y=read();
110                 L=id[edge[x].x];
111                 update(1,1,n,y);
112             }
113             else{
114                 x=read(),y=read();
115                 lca(x,y);
116             }
117         }
118     }
119     return 0;
120 }

 

以上是关于FZU 2082(过路费)的主要内容,如果未能解决你的问题,请参考以下文章

FZU1004-Number Triangle经典动归题,核心思路及代码优化

如何用python实现算法,得到两个城市间的最优路径,综合考虑油费和过路费

2017福建省赛 FZU2272~2283

FZU 2169 shadow

FZU 2020 组合 (Lucas定理)

FZU 2122 又见LKity