zoukankan      html  css  js  c++  java
  • CF840E In a Trap

    题意:给你一棵节点带权树。q个询问,每次询问u到v的路径上max(a[i]^dis(i,v))?

    保证u是v的祖先,i是u->v路径上的点。n,ai<=5e4。

    标程:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int read()
     4 {
     5    int x=0,f=1;char ch=getchar();
     6    while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
     7    while (ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
     8    return x*f;
     9 }
    10 const int N=50005;
    11 int cnt,n,q,u,v,a[N],dep[N],head[N],fa[N],sc,son[5000][2],t,c,now,sum,f[N][260],jp[N],ans,base;
    12 struct node{int to,next;}num[N*2];
    13 void add(int x,int y)
    14 {num[++cnt].to=y;num[cnt].next=head[x];head[x]=cnt;}
    15 void dfs(int x)
    16 {
    17     for (int i=head[x];i;i=num[i].next)
    18       if (num[i].to!=fa[x]) {
    19         dep[num[i].to]=dep[x]+1;
    20           fa[num[i].to]=x;
    21           dfs(num[i].to);
    22       }
    23 }
    24 int main()
    25 {
    26     n=read();q=read();
    27     for (int i=1;i<=n;i++) a[i]=read();
    28     for (int i=1;i<n;i++) u=read(),v=read(),add(u,v),add(v,u);
    29     dfs(1);
    30     for (int i=1;i<=n;i++)
    31       if (dep[i]>=255)
    32       {
    33          int x=i;sc=0;son[0][0]=son[0][1]=0;
    34          for (int j=0;j<256;j++,x=fa[x])//add_Trie
    35          {
    36            t=a[x]^j;now=0;
    37            for (int k=16;k>=0;k--)
    38            {
    39                c=(t>>k)&1;
    40                if (!son[now][c]) son[now][c]=++sc,son[sc][0]=son[sc][1]=0;
    41                now=son[now][c];
    42             }
    43          }
    44          for (int j=0;j<256;j++)
    45          {
    46              t=j<<8;now=sum=0;
    47              for (int k=16;k>=0;k--)
    48              {
    49                  c=(t>>k)&1;
    50                  if (son[now][c^1]) now=son[now][c^1],sum+=(1<<k);else now=son[now][c];
    51             }
    52              f[i][j]=sum;
    53          }
    54          jp[i]=x;
    55     }
    56    while (q--)
    57    {
    58        u=read();v=read();ans=base=0;
    59        for (;dep[v]-dep[u]>=255;v=jp[v]) ans=max(ans,f[v][base]),base++;
    60        for (base=base*256;v!=fa[u];v=fa[v],base++) ans=max(ans,a[v]^base);
    61        printf("%d
    ",ans);
    62     }
    63    return 0;
    64 }

    题解:分块+Trie

    异或性质:比如需要异或x,那么^(x&255)^((x>>8)<<8)等价。拆数异或值不变。

    对于每个点到根的链,每256个分一个块。

    每个点x保存f[x][i]表示从x以上256个点的块中max(a[j]^dis(x,j)^(i<<8))。容易用字典树处理出所有i的最大异或值。

    查询的时候按照块跳。统计max(f[v][base]),每次base++。

    时间复杂度O(q*256+n*256*logn)。

  • 相关阅读:
    导入导出
    封装本地文件路径
    读书书单
    Spring源码阅读-BeanFactory体系结构分析
    Spring源码阅读-ApplicationContext体系结构分析
    Spring源码阅读-IoC容器解析
    Spring源码阅读环境搭建
    【spring实战第五版遇到的坑】第14章spring.cloud.config.uri和token配置项无效
    【spring实战第五版遇到的坑】4.2.3中LDAP内嵌服务器不启动的问题
    【spring实战第五版遇到的坑】3.2中配置关系映射时,表名和3.1中不一样
  • 原文地址:https://www.cnblogs.com/Scx117/p/9110402.html
Copyright © 2011-2022 走看看