zoukankan      html  css  js  c++  java
  • bzoj4568: [Scoi2016]幸运数字(LCA+线性基)

    4568: [Scoi2016]幸运数字

    题目:传送门


    题解:

       好题!!!

       之前就看过,当时说是要用线性基...就没学

       填坑填坑:

       %%%线性基 && 神犇

       主要还是对于线性基的运用和LCA的灵活运用吧:

       设f[i][j][65]表示i到2^j-1的线性基集合

       跑LCA,边跑边暴力合并路径上的线性基咯,最后find_max一下xor的最大值就好啦

       槽点:注意^符号的优先级还有空间大小...有点恶心


    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cmath>
      5 #include<algorithm>
      6 using namespace std;
      7 typedef long long LL;
      8 struct node
      9 {
     10     int x,y,next;
     11 }a[41000];int len,last[21000];
     12 void ins(int x,int y)
     13 {
     14     len++;a[len].x=x;a[len].y=y;
     15     a[len].next=last[x];last[x]=len;
     16 }
     17 void add(LL *a,LL x)
     18 {
     19     for(int i=60;i>=0;i--)
     20     {
     21         if(x&(1LL<<i))
     22         {
     23             if(!a[i]){a[i]=x;break;}
     24             x^=a[i];
     25         }
     26     }
     27 }
     28 void merge(LL *a,LL *b)
     29 {
     30     for(int i=0;i<=60;i++)
     31         if(b[i])add(a,b[i]);
     32 }
     33 LL ans[65],bin[65],f[21000][21][65],dep[21000],fa[21000][21];
     34 void pre_tree_node(int x)
     35 {
     36     for(int i=1;bin[i]<=dep[x];i++)
     37     {
     38         fa[x][i]=fa[fa[x][i-1]][i-1];
     39         memcpy(f[x][i],f[x][i-1],sizeof(f[x][i]));
     40         merge(f[x][i],f[fa[x][i-1]][i-1]);
     41     }
     42     for(int k=last[x];k;k=a[k].next)
     43     {
     44         int y=a[k].y;
     45         if(y!=fa[x][0])
     46         {
     47             fa[y][0]=x;
     48             dep[y]=dep[x]+1;
     49             pre_tree_node(y);
     50         }
     51     }
     52 }
     53 void solve(int x,int y)
     54 {
     55     if(dep[x]<dep[y])swap(x,y);
     56     for(int i=20;i>=0;i--)
     57         if(dep[fa[x][i]]>=dep[y])
     58             merge(ans,f[x][i]),x=fa[x][i];
     59     if(x==y){merge(ans,f[x][0]);return ;}
     60     for(int i=20;i>=0;i--)
     61         if(bin[i]<=dep[x] && fa[x][i]!=fa[y][i])
     62         {
     63             merge(ans,f[x][i]),merge(ans,f[y][i]);
     64             x=fa[x][i],y=fa[y][i];
     65         }
     66     merge(ans,f[x][0]),merge(ans,f[y][0]);
     67     merge(ans,f[fa[x][0]][0]);
     68     return ;
     69 }
     70 LL find_max()
     71 {
     72     LL sum=0;
     73     for(int i=60;i>=0;i--)
     74         if((sum^ans[i])>sum)
     75             sum^=ans[i];
     76     return sum;
     77 }
     78 int n,T;
     79 int main()
     80 {
     81     scanf("%d%d",&n,&T);
     82     bin[0]=1LL;for(int i=1;i<=60;i++)bin[i]=bin[i-1]<<1;
     83     len=0;memset(last,0,sizeof(last));
     84     for(int i=1;i<=n;i++)
     85     {
     86         LL x;scanf("%lld",&x);
     87         add(f[i][0],x);
     88     }
     89     for(int i=1;i<n;i++)
     90     {
     91         int x,y;scanf("%d%d",&x,&y);
     92         ins(x,y);ins(y,x);
     93     }
     94     fa[1][0]=0;dep[1]=1;pre_tree_node(1);
     95     while(T--)
     96     {
     97         int x,y;scanf("%d%d",&x,&y);
     98         memset(ans,0,sizeof(ans));
     99         solve(x,y);
    100         printf("%lld
    ",find_max());
    101     }
    102     return 0;
    103 }
  • 相关阅读:
    易语言破解与安装
    用 AS3.0 的 fscommand 命令调用 .exe 文件。
    swf批量导出
    pureMVC java版搭建流程
    PureMVC 框架总结收录
    一些算法
    练习3.34
    关于数组的注意事项
    练习3.30、3.33
    练习3.27、3.28、3.29
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8538748.html
Copyright © 2011-2022 走看看