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经典动归题,核心思路及代码优化