[hackerrank]Self-Driving Bus
2017-02-24 22:23
393 查看
题目大意
一颗n个节点的树,现在问有多少对[l,r]满足保留编号[l,r]的点在树上是联通块。n<=1e5
点剖
点分治一波一个联通块要么包含分治中心,要么不包括,后者递归分治处理。
假设分治中心编号为x。用fa表示在树上的父亲(以x为根)
我们找到极大区间[l,r]包含x使得编号[l,r]都出现了。
把合法的左端和右端都提取出来(合法的左端i即[i,x]没有fa会连到i左边,合法右端i即[x,i]没有fa会连到i右边)
枚举每一个合法左端,得出哪个区间的合法右端是可选的,来计算答案。
#include<cstdio> #include<algorithm> #define fo(i,a,b) for(i=a;i<=b;i++) #define fd(i,a,b) for(i=a;i>=b;i--) using namespace std; typedef long long ll; const int maxn=200000+10; int h[maxn],go[maxn*2],nxt[maxn*2],size[maxn],a[maxn],fa[maxn],b[maxn][2],c[maxn][2]; int d[maxn]; bool bz[maxn]; int i,j,k,l,r,t,n,m,tot,top,cnt,num; ll ans; int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return x*f; } void add(int x,int y){ go[++tot]=y; nxt[tot]=h[x]; h[x]=tot; } void travel(int x,int y){ int t=h[x]; size[x]=1; while (t){ if (!bz[go[t]]&&go[t]!=y){ travel(go[t],x); size[x]+=size[go[t]]; } t=nxt[t]; } } void dfs(int x,int y){ fa[x]=y; a[++top]=x; int t=h[x]; while (t){ if (!bz[go[t]]&&go[t]!=y) dfs(go[t],x); t=nxt[t]; } } void calc(int x){ int i,j,k,t,l,r; fo(i,1,top) d[a[i]]=1; l=r=x; while (l>1&&d[l-1]) l--; while (r<n&&d[r+1]) r++; fa[x]=x; cnt=0; t=n+1;k=0; fd(i,x,l){ t=min(t,fa[i]); k=max(k,fa[i]); if (t>=i){ b[++cnt][0]=i; b[cnt][1]=k; } } num=0; t=n+1;k=0; fo(i,x,r){ t=min(t,fa[i]); k=max(k,fa[i]); if (k<=i){ c[++num][0]=i; c[num][1]=t; } } j=k=1; fo(i,1,cnt){ while (j<=num&&c[j][0]<b[i][1]) j++; while (k<num&&c[k+1][1]>=b[i][0]) k++; if (j<=k) ans+=(ll)(k-j+1); } fo(i,1,top) d[a[i]]=0; } void solve(int x){ travel(x,0); int j=x,k=0,t; while (1){ t=h[j]; while (t){ if (!bz[go[t]]&&go[t]!=k&&size[go[t]]>top/2){ k=j; j=go[t]; break; } t=nxt[t]; } if (!t) break; } top=0; dfs(j,0); calc(j); bz[j]=1; t=h[j]; while (t){ if (!bz[go[t]]) solve(go[t]); t=nxt[t]; } } int main(){ n=read(); fo(i,1,n-1){ j=read();k=read(); add(j,k);add(k,j); } solve(1); printf("%lld\n",ans); }
相关文章推荐
- HackerRank "Self Balancing Tree"
- HackerRank Self Balancing Tree(AVL树)
- HackerRank "Components in a graph"
- HackerRank "Vertical Rooks"
- HackerRank "Kitty and Katty"
- HackerRank Week of Code 23——Enclosure(等周定理+余弦定理)
- Hackerrank 101 Hack 42 Array Pairs
- 【Hacker Rank】04.Arithmetic Operators
- Hackerrank Random Number Generator
- Hackerrank——Week of Code 27
- HackerRank - gcd-matrix
- Python HackerRank|Lists
- HackerRank - almost-sorted-interval (思维)
- Python HackerRank|Collections.deque()(from collections import deque)
- HackerRank网站,为编码程序员们提供一个以编码谜题和现实生活中遇到的编码难题为基础的新兴的社交平台
- HackerRank Medium(30) Super Six Substrings DP+数学
- C++ HackerRank|AND xor OR
- hackerrank>Dashboard>C++>STL> Maps-STL
- HackerRank Pattern Count 题解
- HackerRank - pairs-again(暴力+预处理)