zoukankan      html  css  js  c++  java
  • bzoj 5338: [TJOI2018]xor (树链剖分+可持久化01Trie)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=5338

    题面:

    5338: [TJOI2018]xor

    Time Limit: 30 Sec  Memory Limit: 256 MB
    Submit: 269  Solved: 171
    [Submit][Status][Discuss]

    Description

    现在有一颗以1为根节点的由n个节点组成的树,树上每个节点上都有一个权值vi。
    现在有Q 次操作,操作如下:
    1  x y    查询节点x的子树中与y异或结果的最大值
    2 x y z    查询路径x到y上点与z异或结果最大值
     

    Input

    第一行是两个数字n, Q;
    第二行是n个数字用空格隔开,第i个数字vi表示点i上的权值 
    接下来n-1行,每行两个数,x,y,表示节点x与y之间有边 
    接下来Q行,每一行为一个查询,格式如上所述.
    1 < n, Q ≤ 100000 ,查询1中的y ≤ 2^30 ,查询2中的z ≤ 2^30
     

    Output

    对于每一个查询,输出一行,表示满足条件的最大值。
     

    Sample Input

    7 5
    1 3 5 7 9 2 4
    1 2
    1 3
    2 4
    2 5
    3 6
    3 7
    1 3 5
    2 4 6 3
    1 5 5
    2 5 7 2
    1 1 9

    Sample Output

    7
    6
    12
    11
    14
     
    实现代码;
    #include<bits/stdc++.h>
    using namespace std;
    const int M = 2e5+10;
    struct node{
        int to,next;
    }e[M];
    int cnt,cnt1,n;
    int son[M],siz[M],head[M],fa[M],top[M],dep[M],tid[M],mx[M],rk[M];
    void add(int u,int v){
        e[++cnt].to = v;e[cnt].next = head[u];head[u] = cnt;
    }
    
    void dfs1(int u,int faz,int deep){
        dep[u] = deep;
        fa[u] = faz;
        siz[u] = 1;
        for(int i = head[u];i;i = e[i].next){
            int v = e[i].to;
            if(v == faz) continue;
            dfs1(v,u,deep+1);
            siz[u] += siz[v];
            if(siz[v] > siz[son[u]]||son[u] == -1)
                son[u] = v;
        }
    }
    
    void dfs2(int u,int t){
        top[u] = t;
        tid[u] = ++cnt1;
        mx[u] = cnt1;
        rk[cnt1] = u;
        if(son[u] == -1) return ;
        dfs2(son[u],t);
        for(int i = head[u];i;i=e[i].next){
            int v = e[i].to;
            if(v != fa[u]&&v != son[u])
                dfs2(v,v);
        }
        mx[u] = cnt1;
    }
    
    struct node1{
        int s[2],v;
    }t[M*50];
    int idx,rt[M];
    void update(int &k,int p,int w){
        t[++idx] = t[k]; k = idx; t[k].v++;
        if(w == -1) return ;
        if(p&(1<<w)) update(t[k].s[1],p,w-1);
        else update(t[k].s[0],p,w-1);
    }
    
    int query(int old,int k,int p,int w){
        if(w == -1) return 0;
        int c= (bool)(p&(1<<w));
        if(t[t[k].s[c^1]].v - t[t[old].s[c^1]].v)
            return query(t[old].s[c^1],t[k].s[c^1],p,w-1)|(1<<w);
        else
            return query(t[old].s[c],t[k].s[c],p,w-1);
    }
    
    int ask(int x,int y,int z){
        int ans = 0;
        int fx = top[x],fy = top[y];
        while(fx != fy){
            if(dep[fx] < dep[fy]) swap(x,y),swap(fx,fy);
            ans = max(ans,query(rt[tid[fx]-1],rt[tid[x]],z,30));
            x = fa[fx]; fx = top[x];
        }
        if(dep[x] > dep[y]) swap(x,y);
        ans = max(ans,query(rt[tid[x]-1],rt[tid[y]],z,30));
        return ans;
    }
    int a[M];
    int main()
    {
        int n,q,u,v,x,y,z,op;
        scanf("%d%d",&n,&q);
        memset(son,-1,sizeof(son));
        for(int i = 1;i <= n;i ++) scanf("%d",&a[i]);
        for(int i = 1;i < n;i ++){
            scanf("%d%d",&u,&v);
            add(u,v); add(v,u);
        }
        dfs1(1,0,1); dfs2(1,1);
        for(int i = 1;i <= n;i ++) rt[i]=rt[i-1],update(rt[i],a[rk[i]],30);
        while(q--){
            scanf("%d%d%d",&op,&x,&y);
            if(op == 1){
                printf("%d
    ",query(rt[tid[x]-1],rt[mx[x]],y,30));
            }
            else{
                scanf("%d",&z);
                printf("%d
    ",ask(x,y,z));
            }
        }
        return 0;
    }
  • 相关阅读:
    $scope.$watch监听
    git 修改地址,及提交返回403错误原因
    wepy wx:getLocation 配置 permission
    vue-cli 3.x 导入jquety
    微信小程序、微信公众号、H5之间相互跳转
    微信小程序之滚动选择器
    软件开发过程中所需要的文档
    Git 常用命令详解
    小程序填坑--TypeError: this.setData is not a function
    使用tomcat时,不用给webapps文件放入文件,直接访问项目方法
  • 原文地址:https://www.cnblogs.com/kls123/p/10764909.html
Copyright © 2011-2022 走看看