设计网站如何推广,网站的数据库怎么备份,同城招聘工作信息附近,购物正题
题目链接:https://jzoj.net/senior/#contest/show/3017/1 题目大意 nnn个点的一棵树#xff0c;mmm次操作#xff0c;修改一个地方的宝藏。
每次操作后求拿完所以宝藏并回到原地的最小距离。 解题思路
显然起点在任何一个有宝藏的地方都是最优的#xff0c;而且顺着…正题
题目链接:https://jzoj.net/senior/#contest/show/3017/1 题目大意
nnn个点的一棵树mmm次操作修改一个地方的宝藏。
每次操作后求拿完所以宝藏并回到原地的最小距离。 解题思路
显然起点在任何一个有宝藏的地方都是最优的而且顺着dfsdfsdfs序走是最优的。
所以对于每次加入的宝藏我们用二分树状数组找出两边dfsdfsdfs序最近的然后用LCALCALCA对距离进行计算即可。
时间复杂度O(nlog2n)O(n\log^2 n)O(nlog2n) codecodecode
#includecstdio
#includecstring
#includealgorithm
#define ll long long
#define lowbit(x) (x-x)
using namespace std;
const ll N2e510,T18;
struct node{ll to,next,w;
}a[N*2];
ll tot,ls[N],f[N][T];
ll dfn[N],rfn[N],dep[N],dis[N],cnt;
ll n,m,ans;
bool v[N];
struct Tree_Array{ll t[N];void Change(ll x,ll val){while(x2*n){t[x]val;xlowbit(x);}return;}ll Ask(ll x){ll ans0;while(x){anst[x];x-lowbit(x);}return ans;}ll Query(ll l,ll r){return Ask(r)-Ask(l-1);}ll Get_Pre(ll x){ll l1,rn;if(Ask(x)0)return 0;while(lr){ll mid(lr)1;if(Query(max(x-mid,1ll),x)0) rmid-1;else lmid1;}return max(x-l,1ll);}ll Get_Aft(ll x){ll l1,rn;if(Ask(n*2)-Ask(x)0)return 0;while(lr){ll mid(lr)1;if(Query(x,min(xmid,n*2))0) rmid-1;else lmid1;}return min(xl,n*2);}
}TA;
void addl(ll x,ll y,ll w){a[tot].toy;a[tot].nextls[x];ls[x]tot;a[tot].ww;
}
void dfs(ll x,ll fa){dfn[cnt]x;rfn[x]cnt;for(ll ils[x];i;ia[i].next){ll ya[i].to;if(yfa) continue;f[y][0]x;dep[y]dep[x]1;dis[y]dis[x]a[i].w;dfs(y,x);}return;
}
ll pref(ll x){ll z;if(zTA.Get_Pre(rfn[x])) return dfn[z];return dfn[TA.Get_Pre(rfn[x]n)];
}
ll aftf(ll x){ll z;if(zTA.Get_Aft(rfn[x]n)) return dfn[z];return dfn[TA.Get_Aft(rfn[x])];
}
ll LCA(ll x,ll y){if(dep[x]dep[y]) swap(x,y);for(ll iT-1;i0;i--)if(dep[f[y][i]]dep[x])yf[y][i];if(xy) return y;for(ll iT-1;i0;i--)if(f[y][i]!f[x][i])xf[x][i],yf[y][i];return f[x][0];
}
ll get_dis(ll x,ll y)
{return dis[x]dis[y]-2*dis[LCA(x,y)];}
int main()
{scanf(%lld%lld,n,m);for(ll i1;in;i){ll x,y,w;scanf(%lld%lld%lld,x,y,w);addl(x,y,w);addl(y,x,w);}dep[0]-1;dfs(1,0);for(ll i1;in;i)dfn[in]dfn[i]; for(ll i1;iT;i)for(ll j1;jn;j)f[j][i]f[f[j][i-1]][i-1];ll w0;while(m--){ll x;scanf(%lld,x);if(v[x]){v[x]0;w--;TA.Change(rfn[x],-1);TA.Change(rfn[x]n,-1);if(w){ll lpref(x),raftf(x);ansans-get_dis(l,x)-get_dis(x,r)get_dis(l,r); }}else{if(w){ll lpref(x),raftf(x);ansansget_dis(l,x)get_dis(x,r)-get_dis(l,r); }v[x]1;w;TA.Change(rfn[x],1);TA.Change(rfn[x]n,1);}printf(%lld\n,ans);}
}