zoukankan      html  css  js  c++  java
  • P4592 [TJOI2018]异或

    题目描述

    现在有一颗以1为根节点的由n个节点组成的树,树上每个节点上都有一个权值vi。现在有Q次操作,操作如下:

    • y:查询节点x的子树中与y异或结果的最大值
    • z:查询路径x到y上点与z异或结果最大值

    输入输出格式

    输入格式:

     

    第一行是两个数字n,Q;

    第二行是n个数字用空格隔开,第i个数字vi表示点i上的权值

    接下来n1行,每行两个数,x,y,表示节点x与y之间有边

    接下来Q行,每一行为一个查询,格式如上所述.

     

    输出格式:

     

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

     

    输入输出样例

    输入样例#1: 
    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
    输出样例#1: 
    7
    6
    12
    11
    14

    说明

    对于10%的数据,有1<n,Q100

    对于20%的数据,有1<n,Q1000

    对于40%的数据,有1<n,Q10000

    对于100%的数据,有1<n,Q100000

    对于100%的数据,有查询1中的y230,查询2中的z230

    Solution:

      本题可持久化trie树。

      最大异或和都会吧,本题不过是把操作放到了树上罢了。

      对于操作$1$:在子树中选取某一信息,明摆着dfs序弄出来,用可持久化trie树维护一下dfs序的节点权值,询问只要在子树的dfs序中贪心就好了。

      对于操作$2$:查询树上路径,那么就跑lca嘛,用可持久化trie树自上而下维护根节点到每个节点的链的节点权值,对于询问$x,y$,在$s_x-s_{lca(x,y)-1}+s_y-s_{lca(x,y)}$的节点信息中贪心就好了。

    代码:

    /*Code by 520 -- 9.29*/
    #include<bits/stdc++.h>
    #define il inline
    #define ll long long
    #define RE register
    #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
    #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
    using namespace std;
    const int N=100005;
    int n,m,val[N],rt1[N],rt2[N],cnt1,cnt2;
    int fa[N][21],dep[N],to[N<<1],net[N<<1],h[N],ec;
    int inc[N],ouc[N],ppx;
    struct node{
        int son[2],tot;    
    }t1[N*80],t2[N*80];
    
    int gi(){
        int a=0;char x=getchar();
        while(x<'0'||x>'9') x=getchar();
        while(x>='0'&&x<='9') a=(a<<3)+(a<<1)+(x^48),x=getchar();
        return a;    
    }
    
    il void add(int u,int v){to[++ec]=v,net[ec]=h[u],h[u]=ec;}
    
    void ins1(int &rt,int lst,int d,int v){
        t1[rt=++cnt1]=t1[lst],t1[rt].tot++;
        if(d<0) return;
        int p=v&(1<<d)?1:0;
        ins1(t1[rt].son[p],t1[lst].son[p],d-1,v);
    }
    
    int query1(int l,int r,int d,int v,int ans){
        if(d<0) return ans;
        int p=v&(1<<d)?1:0,ls=t1[t1[l].son[p^1]].tot,rs=t1[t1[r].son[p^1]].tot;
        if(rs-ls) return query1(t1[l].son[p^1],t1[r].son[p^1],d-1,v,ans|(1<<d));
        return query1(t1[l].son[p],t1[r].son[p],d-1,v,ans);    
    }
    
    void ins2(int &rt,int lst,int d,int v){
        t2[rt=++cnt2]=t2[lst],t2[rt].tot++;
        if(d<0) return;
        int p=v&(1<<d)?1:0;
        ins2(t2[rt].son[p],t2[lst].son[p],d-1,v);
    }
    
    int query2(int lx,int rx,int ly,int ry,int d,int v,int ans){
        if(d<0) return ans;
        int p=v&(1<<d)?1:0,ls=t2[t2[lx].son[p^1]].tot+t2[t2[ly].son[p^1]].tot,rs=t2[t2[rx].son[p^1]].tot+t2[t2[ry].son[p^1]].tot;
        if(rs-ls) return query2(t2[lx].son[p^1],t2[rx].son[p^1],t2[ly].son[p^1],t2[ry].son[p^1],d-1,v,ans|(1<<d));
        return query2(t2[lx].son[p],t2[rx].son[p],t2[ly].son[p],t2[ry].son[p],d-1,v,ans);
    }
    
    void dfs(int u){
        inc[u]=++ppx;
        ins1(rt1[inc[u]],rt1[inc[u]-1],30,val[u]);
        ins2(rt2[u],rt2[u],30,val[u]);
        for(RE int i=h[u];i;i=net[i])
            if(to[i]!=fa[u][0]){
                fa[to[i]][0]=u,dep[to[i]]=dep[u]+1,rt2[to[i]]=rt2[u];
                dfs(to[i]);    
            }
        ouc[u]=ppx;
    }
    
    il int lca(int x,int y){
        if(dep[x]<dep[y]) swap(x,y);
        int dd=dep[x]-dep[y];
        For(i,0,20) if(dd&(1<<i)) x=fa[x][i];
        if(x==y) return x;
        Bor(i,0,20) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
        return fa[x][0];
    }
    
    int main(){
        n=gi(),m=gi();
        For(i,1,n) val[i]=gi();
        int opt,x,y,z,tp;
        For(i,1,n-1) x=gi(),y=gi(),add(x,y),add(y,x);
        dfs(1);
        For(j,1,20) For(i,1,n) fa[i][j]=fa[fa[i][j-1]][j-1];
        while(m--){
            opt=gi(),x=gi(),y=gi();
            if(opt==1) printf("%d
    ",query1(rt1[inc[x]-1],rt1[ouc[x]],30,y,0));
            else {
                z=gi(),tp=lca(x,y);
                printf("%d
    ",query2(rt2[fa[tp][0]],rt2[x],rt2[tp],rt2[y],30,z,0));
            }
        }
        return 0;    
    }
  • 相关阅读:
    《JavaScript 源码分析》之 jquery.unobtrusive-ajax.js
    《JavaScript高级程序设计》读书笔记 2
    《JS设计模式笔记》构造函数和工厂模式创建对象
    《ES6基础教程》之 map、forEach、filter indexOf 用法
    《JS设计模式笔记》 5,适配器模式
    51Nod 1058 N的阶乘的长度
    ACM总结——2017区域赛网络赛总结
    ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 题目9 : Minimum
    hiho一下 第168周
    Fast Matrix Calculation HDU
  • 原文地址:https://www.cnblogs.com/five20/p/9727905.html
Copyright © 2011-2022 走看看