• bzoj4568: [Scoi2016]幸运数字 线性基 倍增


    洛谷T了,mmp

    还是bzoj时限良心,虽然三天两头爆炸

    算是简单的题吧,构造出每个点logn个的线性基表

    感觉线性基最nb的就是只有log个,所以可以做的很暴力

    合并就是拆开再并

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 struct Bas
     4 {
     5     long long a[61];
     6     Bas()
     7     {
     8         for(int i=0;i<=60;i++)
     9             a[i]=0;
    10     }
    11     void add(long long x)
    12     {
    13         for(int i=60;i>=0;i--)
    14         if((x>>i-1)&1)
    15         if(a[i]) x^=a[i];
    16         else
    17         {
    18             a[i]=x;
    19             return;
    20         }
    21     }
    22     long long que()
    23     {
    24         long long ret=0;
    25         for(int i=60;i>=0;i--)
    26         if((ret^a[i])>ret)
    27             ret^=a[i];
    28         return ret;
    29     }
    30 } ba[20001][16];
    31 int n,m,E,p,q;
    32 long long w[20001];
    33 int fa[20001][16],dep[20001];
    34 int fir[20001],nex[40001],to[40001];
    35 Bas merge(Bas a,Bas b)
    36 {
    37     for(int i=0;i<=60;i++)
    38     if(a.a[i]) b.add(a.a[i]); 
    39     return b;
    40 }
    41 void add(int x,int y)
    42 {
    43     to[++E]=y;nex[E]=fir[x];fir[x]=E;
    44 }
    45 void build(int now,int ft)
    46 {
    47     fa[now][0]=ft;dep[now]=dep[ft]+1;
    48     for(int i=0;fa[now][i];i++)
    49         fa[now][i+1]=fa[fa[now][i]][i],
    50         ba[now][i+1]=merge(ba[now][i],ba[fa[now][i]][i]);
    51     for(int i=fir[now];i;i=nex[i])
    52     if(to[i]!=ft)
    53         build(to[i],now);
    54 }
    55 int main()
    56 {
    57     scanf("%d%d",&n,&m);
    58     for(int i=1;i<=n;i++)
    59     {
    60         scanf("%lld",&w[i]);
    61         ba[i][0].add(w[i]);
    62     }
    63     for(int i=1;i<n;i++)
    64         scanf("%d%d",&p,&q),add(p,q),add(q,p);
    65     build(1,0);
    66     for(int i=1;i<=m;i++)
    67     {
    68         scanf("%d%d",&p,&q);
    69         Bas ret=Bas();
    70         if(dep[p]<dep[q]) swap(p,q);
    71         for(int i=15;dep[p]>dep[q];i--)
    72         if(dep[p]-dep[q]>>i)
    73         {
    74             ret=merge(ret,ba[p][i]);
    75             p=fa[p][i];
    76         }
    77         for(int i=15;i>=0;i--)
    78         if(fa[p][i]!=fa[q][i])
    79             ret=merge(merge(ba[p][i],ba[q][i]),ret),
    80             p=fa[p][i],q=fa[q][i];
    81         if(p!=q)
    82         {
    83             ret=merge(merge(ba[p][0],ba[q][0]),ret);
    84             p=fa[p][0];q=fa[q][0];
    85         }
    86         ret=merge(ba[p][0],ret);
    87         printf("%lld
    ",ret.que());
    88     }
    89     return 0;
    90 } 
  • 相关阅读:
    基于物品属性的过滤
    第一个极小的机器学习的应用
    基于物品过滤的Slope One 算法
    【转】Python爬虫(1)_基本原理
    程序猿面试题集锦
    Django:popup弹出框简单应用实例
    【转】Python max内置函数详细介绍
    MySQL数据库(9)_MySQL数据库常用操作命令
    【转】Python的hasattr() getattr() setattr() 函数使用方法详解
    Git常用命令
  • 原文地址:https://www.cnblogs.com/wanglichao/p/7257151.html
Copyright © 2020-2023  润新知