日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

南昌邀请赛 J. Distance on the tree

發布時間:2024/1/1 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 南昌邀请赛 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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。