标签:
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 470 Accepted Submission(s): 97
这个题有点裸,以为LCA是满足结合律的,所以直接拿个线段树来搞就可以了~
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <cstring> #include <algorithm> #include <queue> #include <cstdio> using namespace std ; typedef long long LL ; const int N = 400030 ; const int DEG = 30 ; int n , lca[N<<2] ; struct Edge { int to,next; }edge[N*2]; int head[N],tot; void addedge(int u,int v) { edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } void init() { tot = 0; memset(head,-1,sizeof(head)); } int fa[N][DEG] , deg[N]; void BFS(int root) { queue<int>que; deg[root] = 0; fa[root][0] = root; que.push(root); while(!que.empty()) { int tmp = que.front(); que.pop(); for(int i = 1;i < DEG;i++) fa[tmp][i] = fa[fa[tmp][i-1]][i-1]; for(int i = head[tmp]; i != -1;i = edge[i].next) { int v = edge[i].to; if(v == fa[tmp][0])continue; deg[v] = deg[tmp] + 1; fa[v][0] = tmp; que.push(v); } } } int LCA(int u,int v) { if(deg[u] > deg[v])swap(u,v); int hu = deg[u], hv = deg[v]; int tu = u, tv = v; for(int det = hv-hu, i = 0; det ;det>>=1, i++) if(det&1) tv = fa[tv][i]; if(tu == tv)return tu; for(int i = DEG-1; i >= 0; i--) { if(fa[tu][i] == fa[tv][i]) continue; tu = fa[tu][i]; tv = fa[tv][i]; } return fa[tu][0]; } #define root 1,n,1 #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define lr rt<<1 #define rr rt<<1|1 void Up( int rt ) { lca[rt] = LCA( lca[lr] , lca[rr] ) ; } void build( int l , int r , int rt ) { if( l == r ) { lca[rt] = l ; return ; } int mid = (l+r) >> 1 ; build(lson),build(rson); Up(rt); } int query( int l , int r , int rt , int L , int R ) { if( L == l && r == R ) return lca[rt] ; int mid = (l+r) >> 1 ; if( R <= mid ) return query( lson , L , R ) ; else if( L > mid ) return query( rson , L , R ) ; else return LCA( query( lson , L , mid ) , query( rson , mid + 1 , R ) ) ; } int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif // LOCAL while( ~scanf("%d",&n) ) { init(); for( int i = 1 ; i < n ; ++i ) { int u , v ; scanf("%d%d",&u,&v); addedge( u , v ) ; addedge( v , u ) ; } BFS(1); build(root) ; int q ; scanf("%d",&q); while( q-- ) { int x , y ; scanf("%d%d",&x,&y); printf("%d\n",query(root,x,y)); } } return 0 ; }
HDU 5266 pog loves szh III ( LCA + SegTree||RMQ )
标签:
原文地址:http://www.cnblogs.com/hlmark/p/4562397.html