zoukankan      html  css  js  c++  java
  • [DFS序上建可持久化字典树贪心异或最大值] Query on A Tree HDU

    题意:给出一颗树和Q个询问

    对于每个询问 x y

    你需要搞出 x 节点 子树上一点 (包括自己) 与 y 值异或的最大值

     解题思路:

    套路题

    子树 → dfs序

    异或极值 → trie树

    dfs + trie → 可持久化trie

    按连续序列建树即可

    代码


    /*
        Zeolim - An AC a day keeps the bug away
    */
     
    //#pragma GCC optimize(2)
    //#pragma GCC ("-W1,--stack=128000000")
    #include <bits/stdc++.h>
    using namespace std;
    #define mp(x, y) make_pair(x, y)
    #define fr(x, y, z) for(int x = y; x < z; ++x)
    #define pb(x) push_back(x)
    #define mem(x) memset(x, 0, sizeof(x))
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    typedef std::pair <int, int> pii;
    typedef std::vector <int> vi;
    //typedef __int128 ill;
    const ld PI = acos(-1.0);
    const ld E = exp(1.0);
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll MOD = 386910137;
    const ull P = 13331; 
    const int MAXN = 2e5 + 10;
    
    struct trie
    {
    	int cnt, root[MAXN], tr[MAXN * 30][2], sum[MAXN * 30];
    	trie() {cnt = 0;}
    	void insert(int now, int last, int val) 
    	{
    		int nto, lto;
    		root[now] = nto = ++cnt;
    		lto = root[last];
    		for(int i = 30; i >= 0; --i)
    		{
    			int dig = val >> i & 1;
    			tr[nto][0] = tr[lto][0];
    			tr[nto][1] = tr[lto][1];  		 //½«ÉÏÒ»°æ±¾¶ù×ÓÖ±½Ó¸²¸Ç 
    			tr[nto][dig] = ++cnt, nto = cnt; //µ±Ç°°æ±¾µÄжù×Ó 
    			lto = tr[lto][dig]; 
    			sum[nto] = sum[lto] + 1; 		 //ǰ׺ºÍ + 1 
    		}
    	}
    	int get(int now, int last, int val)
    	{
    		int ret = 0;
    		int nto = root[now], lto = root[last];
    		for(int i = 30; i >= 0; --i)
    		{
    			int dig = val >> i & 1 ^ 1;
    			if(sum[ tr[nto][dig] ] - sum[ tr[lto][dig] ]) //µ±Ç°Çø¼äÄÚÓиÃÄ¿±ê½Úµã 
    				ret += (1 << i), nto = tr[nto][dig], lto = tr[lto][dig];
    			else
    				nto = tr[nto][dig ^ 1], lto = tr[lto][dig ^ 1];
    		}
    		return ret;
    	}
    	void clear()
    	{
    		cnt = 0;
    		mem(sum);
    		mem(tr);
    		mem(root);
    	}
    }T;
    
    int val[MAXN] = {0};
    
    int fa[MAXN] = {0};
    
    vector <int> edge[MAXN];
    
    int arr[MAXN] = {0}, tot = 0;
    
    int in[MAXN] = {0}, out[MAXN] = {0};
    
    void gao(int now)
    {
    	arr[++tot] = val[now];
    	in[now] = tot;
    	for(auto x :edge[now])
    		gao(x);
    	out[now] = tot;
    }
    
    void clear(int n)
    {
    	T.clear();
    	for(int i = 0; i <= n; ++i)
    		edge[i].clear();
    	tot = 0;
    }
    
    int main()
    {  
    	ios::sync_with_stdio(0);
    	cin.tie(0); cout.tie(0);
    	
    	int n, q;
    	
    	while(cin >> n >> q)
    	{
    		clear(n);
    		
    		for(int i = 1; i <= n; ++i)
    			cin >> val[i];
    	
    		for(int i = 2; i <= n; ++i)
    		{
    			cin >> fa[i];
    			edge[fa[i]].push_back(i);
    		}
    		
    		gao(1);
    		
    		T.insert(0, 0, 0);
    		
    		for(int i = 1; i <= n; ++i)
    		{
    			T.insert(i, i - 1, arr[i]);
    		}
    		
    		int x, y;
    		
    		while(q--)
    		{
    			cin >> x >> y;
    			
    			cout << T.get(out[x], in[x] - 1, y) << '
    ';
    		}
    	}
    	
    	
    	
        return 0;
    }
    
    /*
    5 5
    5 2 7 3 1
    3 1 1 3 
    1 5
    3 2
    4 3
    2 1
    5 5
    */
  • 相关阅读:
    369. Plus One Linked List
    147. Insertion Sort List
    817. Linked List Components
    61. Rotate List
    Object 类
    多态
    重写方法
    Protected 修饰符
    继承
    数组
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270345.html
Copyright © 2011-2022 走看看