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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2021牛客暑期多校训练营7 xay loves trees dfs序 + 主席树

發(fā)布時間:2023/12/4 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2021牛客暑期多校训练营7 xay loves trees dfs序 + 主席树 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

傳送門

文章目錄

  • 題意:
  • 思路:

題意:

給你兩棵樹,讓你在第一棵樹選一條最長的深度遞增的鏈,鏈上每一個點在第二棵樹上都不互為祖先。

n≤3e5n\le3e5n3e5

思路:

之前做過差不多的題傳送門。
之前哪個題是不需要連續(xù)的,所以比較好寫,這個題要求連續(xù),即為一條鏈,所以能難點。
比賽的時候?qū)懥藗€滑動窗口假算法,貌似還挺容易就能卡死的。。
直接來說正解吧,考慮dfsdfsdfs序的區(qū)間要么某個區(qū)間全部包含某個區(qū)間,要不就是兩個區(qū)間沒有交集。利用這個性質(zhì),我們考慮在第二棵樹上跑一個dfsdfsdfs序,在第一棵樹上dfsdfsdfs的時候維護根到當(dāng)前點的一條鏈,建立一顆線段樹,當(dāng)?shù)侥硞€點的時候就將這個點的dfsdfsdfs序的區(qū)間全部賦值為depth[u]depth[u]depth[u],查詢的時候只需要查詢一下當(dāng)前點的dfsdfsdfs序區(qū)間[l,r][l,r][l,r]內(nèi)的最大值即可,因為加入當(dāng)前區(qū)間之后只會和[l,r][l,r][l,r]內(nèi)的區(qū)間沖突,所以只需要取區(qū)間最大值后就代表向上最多能跑到的深度+1+1+1,直接與當(dāng)前深度做差即可。注意還需要滿足之前的深度,所以dfsdfsdfs的時候取一個maxmaxmax深度即可。

// Problem: xay loves trees // Contest: NowCoder // URL: https://ac.nowcoder.com/acm/contest/11258/F // Memory Limit: 1048576 MB // Time Limit: 4000 ms // // Powered by CP Editor (https://cpeditor.org)//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native") //#pragma GCC optimize(2) #include<cstdio> #include<iostream> #include<string> #include<cstring> #include<map> #include<cmath> #include<cctype> #include<vector> #include<set> #include<queue> #include<algorithm> #include<sstream> #include<ctime> #include<cstdlib> #include<random> #include<cassert> #define X first #define Y second #define L (u<<1) #define R (u<<1|1) #define pb push_back #define mk make_pair #define Mid ((tr[u].l+tr[u].r)>>1) #define Len(u) (tr[u].r-tr[u].l+1) #define random(a,b) ((a)+rand()%((b)-(a)+1)) #define db puts("---") using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); } //void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); } //void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII;const int N=300010,mod=1e9+7,INF=0x3f3f3f3f; const double eps=1e-6;int n; vector<int>v1[N],v2[N]; int l[N],r[N],tot; int root[N],depth[N]; int ans=0; struct Node {int l,r;int mx,lazy; }tr[N*40];void dfs_dfn(int u,int fa) {l[u]=++tot;for(auto x:v2[u]) {if(x==fa) continue;dfs_dfn(x,u);}r[u]=tot; }void insert(int p,int &q,int l,int r,int ql,int qr,int x) {q=++tot; tr[q]=tr[p]; tr[q].mx=x;if(l>=ql&&r<=qr) {tr[q].lazy=x;return;}int mid=(l+r)>>1;if(ql<=mid) insert(tr[p].l,tr[q].l,l,mid,ql,qr,x);if(qr>mid) insert(tr[p].r,tr[q].r,mid+1,r,ql,qr,x); }int query(int u,int l,int r,int ql,int qr) {if(!u) return 0;int ans=tr[u].lazy;if(l>=ql&&r<=qr) return max(ans,tr[u].mx);int mid=(l+r)>>1;if(ql<=mid) ans=max(ans,query(tr[u].l,l,mid,ql,qr));if(qr>mid) ans=max(ans,query(tr[u].r,mid+1,r,ql,qr));return ans; }void dfs(int u,int fa,int d) {depth[u]=depth[fa]+1; int now=max(d,query(root[fa],1,n,l[u],r[u]));ans=max(ans,depth[u]-now);insert(root[fa],root[u],1,n,l[u],r[u],depth[u]);for(auto x:v1[u]) {if(x==fa) continue;dfs(x,u,now);} }int main() { // ios::sync_with_stdio(false); // cin.tie(0);int _; cin>>_;while(_--) { tot=0;scanf("%d",&n);for(int i=1;i<=n-1;i++) {int a,b; scanf("%d%d",&a,&b);v1[a].pb(b); v1[b].pb(a);}for(int i=1;i<=n-1;i++) {int a,b; scanf("%d%d",&a,&b);v2[a].pb(b); v2[b].pb(a);}dfs_dfn(1,0); tot=0; ans=0;dfs(1,0,0);printf("%d\n",ans);for(int i=1;i<=n;i++) v1[i].clear(),v2[i].clear(),root[i]=0;for(int i=1;i<=tot;i++) tr[i].l=tr[i].r=tr[i].lazy=tr[i].mx=0;}return 0; } /**/

總結(jié)

以上是生活随笔為你收集整理的2021牛客暑期多校训练营7 xay loves trees dfs序 + 主席树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。