zoukankan      html  css  js  c++  java
  • B20J :5165: 树上倍增

    5165: 树上倍增

    Description

    现有一棵树。您需要写一个树上倍增算法,以实现如下操作:
    A x 新建一个节点,将它作为x节点的儿子,编号为当前节点总数+1。
    Q k p1 p2 p3.... 查询p1,p2,p3...这些节点的LCA。其中k表示查询节点的个数。
    最初树上只有一个节点,编号为1。 
    多个节点的LCA定义为:这些节点的公共祖先中深度最大的。

    Input

    第一行,一个正整数,表示操作个数。 
    接下来行,每行输入一个操作,格式如题目描述所述。
    保证任何输入的数都是正整数。
    n≤3000000 k≤1000。
    保证询问不超过1000次

    Output

    对于每一个Q操作,输出一行一个正整数,表示所询问节点的LCA。

    Sample Input

    10
    A 1
    A 2
    A 3
    A 1
    A 5
    A 5
    Q 2 3 6
    Q 2 6 7
    Q 2 4 2
    Q 3 7 6 5

    Sample Output

    1
    5
    2
    5

    思路:

    如题目 : 树上倍增

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cctype>
    using namespace std;
    const int N = 3000001;
    int _, f[21][N], __, dep[N];
    inline char Nc() {
    	static char Buf[100000], *p1, *p2;
    	return p1==p2&&(p2=(p1=Buf)+fread(Buf, 1, 100000, stdin), p1==p2)?EOF:*p1++;
    }
    int Rd() {
    	int x = 0;
    	/*scanf("%d", &x);
    	return x;*/char c = Nc();
    	while(!isdigit(c)) c=Nc();
    	while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=Nc();
    	return x;
    }
    char Gc() {
    	char c = Nc();
    	while(isspace(c)) c = Nc();
    	return c;
    	/*char c[3];
    	scanf("%s", c);
    	return c[0];*/
    }
    int lca(int x, int y) {
    	if(dep[y] < dep[x]) swap(x, y);
    	for(int i=20;i>=0;i--) {
    		if(dep[x] <= dep[y] - (1<<i)) y = f[i][y];
    	}
    	if(x==y)return x;
    	for(int i=20;i>=0;i--) {
    		if(f[i][x] == f[i][y]) continue;
    		x = f[i][x], y = f[i][y];
    	}
    	return f[0][x];
    }
    int main() {
    	int t = Rd();
    	__ = 1;
    	while(t--) {
    		dep[1] = 1;
    		char opt = Gc();
    		if(opt=='A') {
    			int fa = Rd();
    			__++;
    			dep[__] = dep[fa]+1;
    			f[0][__] = fa;
    			for(int i=1;i<=20;i++) {
    				f[i][__] = f[i-1][f[i-1][__]];
    			}
    		}
    		else {
    			int k = Rd();
    			k--;
    			int x, y;
    			x = Rd();
    			while(k--) {
    				y = Rd();
    				if(x!=1) x = lca(x, y);
    			}
    			printf("%d
    ", x);
    		}
    	}
    }
    
  • 相关阅读:
    [Learn AF3]第二章 App Framework 3.0的组件View——AF3的驱动引擎
    [Learn AF3]第一章 如何使用App Framework 3.0 构造应用程序
    [译]Intel App Framework 3.0的变化
    手机浏览器中屏蔽img的系统右键菜单context menu
    HTML5 touche vents drag to move & AF actionsheet by longTap
    HTML5 FileReader
    【转】Gulp入门基础教程
    【Intel AF 2.1 学习笔记三】
    【Intel AF 2.1 学习笔记二】AF中的页面——Panel
    【Intel AF 2.1 学习笔记一】AF程序结构
  • 原文地址:https://www.cnblogs.com/Tobichi/p/9247691.html
Copyright © 2011-2022 走看看