南昌邀请赛 J. Distance on the tree
生活随笔
收集整理的這篇文章主要介紹了
南昌邀请赛 J. Distance on the tree
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
- J. Distance on the tree
題意:
給出n個節點的一顆樹,每條邊都有邊權,m次查詢,每次給出u,v,k,求u到v路徑上邊權小于等于k的邊有多少條
思路:
對邊權和k一起離散化,就把每個操作掛到對應的點上,跑一遍tarjan。向下搜索的時候邊權w,就用樹狀數組維護加到第w個位置,回溯的時候刪掉就行。假設有一個操作 (u,v,k),那么假設搜索到u的時候,那直接就可以用樹狀數組求出根節點到u上小于等于k的邊有a條(回溯的時候有刪邊,那么在樹狀數組中的數一定都是這條路徑上的邊權),搜索到v的時候就可以直接求出根節點到v的路徑上小于等于k的邊有b條,然后此時還可以計算出fa=lca(u,v),那么在fa這個點加個操作,等下回溯的時候算出根節點到fa的路徑上小于等于x的邊有c條,那最后就得到這個操作的答案a+b-2*c。
代碼:
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int>pii; typedef vector<int>vi;#define rep(i,a,b) for(int i=(a);i<(b);i++) #define fi first #define se second #define de(x) cout<<#x<<"="<<x<<endl; #define dd(x) cout<<#x<<"="<<x<<" " ; #define pb(x) push_back(x) #define lowbit(a) ((a)&-(a)) #define per(i,a,b) for(int i=(b)-1;i>=(a);--i) const int N=2e5+5; int p[N],pre[N],ans[N],sum[N]; bool vis[N]; struct edge{int u,v,w; }ed[N]; struct option{int u,v,k; }opt[N]; struct node{int id,w,v;node(int tid,int tw,int tv){id=tid;w=tw;v=tv;} }; map<int,int>mp,dis[N]; vector<pii>G[N],lca[N]; vector<node>op[N]; void add(int x,int y){for(int i=x;i<N;i+=lowbit(i)){sum[i]+=y;} } int getSum(int x){int res=0;for(int i=x;i>=1;i-=lowbit(i))res+=sum[i];return res; } int find_set(int x){if(pre[x]==x)return x;return pre[x]=find_set(pre[x]); } void tarjan(int u){vis[u]=true;for(auto it:G[u]){if(!vis[it.fi]){add(it.se,1);tarjan(it.fi);add(it.se,-1);pre[it.fi]=u;}}for(auto it:lca[u]){ans[it.se]-=2*getSum(it.fi);}for(auto it:op[u]){ans[it.id]+=getSum(it.w);if(vis[it.v]){int fa=find_set(it.v);lca[fa].pb(pii(it.w,it.id)); }} } int main() {memset(vis,0,sizeof(vis));int n,m;scanf("%d%d",&n,&m);rep(i,1,n+1)pre[i]=i; int len=n-1;rep(i,1,n){scanf("%d%d%d",&ed[i].u,&ed[i].v,&ed[i].w);p[i]=ed[i].w;}rep(i,1,m+1){scanf("%d%d%d",&opt[i].u,&opt[i].v,&opt[i].k);p[++len]=opt[i].k;}sort(p+1,p+len+1);int tot=unique(p+1,p+len+1)-p;for(int i=1;i<=len;++i){mp[p[i]]=lower_bound(p+1,p+tot+1,p[i])-p;}rep(i,1,n){G[ed[i].u].pb(pii(ed[i].v,mp[ed[i].w])); G[ed[i].v].pb(pii(ed[i].u,mp[ed[i].w]));}rep(i,1,m+1){op[opt[i].u].pb(node(i,mp[opt[i].k],opt[i].v));op[opt[i].v].pb(node(i,mp[opt[i].k],opt[i].u));}tarjan(1);rep(i,1,m+1){printf("%d\n",ans[i]);}return 0; }總結
以上是生活随笔為你收集整理的南昌邀请赛 J. Distance on the tree的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【手势隔层透传】iOS viewA被vi
- 下一篇: pixy cmucam5接线图