zoukankan      html  css  js  c++  java
  • 洛谷P3292 [SCOI2016]幸运数字(倍增+线性基)

    传送门

    不知道线性基是什么东西的可以看看蒟蒻的总结

    第一眼:这不会是个倍增LCA暴力合并线性基吧……

    打了一发……A了?

    所以这真的是个暴力倍增LCA合并线性基么……

    ps:据某大佬说其实可以离线之后用点分做,那样的话因为每次只要合并两个线性基,复杂度可以减一个$log$

     1 //minamoto
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #define ll long long
     6 #define max(a,b) ((a)>(b)?(a):(b))
     7 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     8 char buf[1<<21],*p1=buf,*p2=buf;
     9 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    10 using namespace std;
    11 inline ll read(){
    12     #define num ch-'0'
    13     char ch;bool flag=0;ll res;
    14     while((ch=getc())>'9'||ch<'0')
    15     (ch=='-')&&(flag=true);
    16     for(res=num;(ch=getc())<='9'&&ch>='0';res=res*10+num);
    17     (flag)&&(res=-res);
    18     #undef num
    19     return res;
    20 }
    21 char sr[1<<21],z[20];int C=-1,Z;
    22 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    23 inline void print(ll x){
    24     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
    25     while(z[++Z]=x%10+48,x/=10);
    26     while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    27 }
    28 const int N=20005;
    29 int n,q,tot,head[N],Next[N<<1],ver[N<<1],dep[N];
    30 ll fa[N][21],b[N][21][62],sum,ans[62],val[N];
    31 inline void add(int u,int v){
    32     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
    33 }
    34 inline void get(ll *b,ll x){
    35     for(int i=61;i>=0;--i)
    36     if(x>>i&1){
    37         if(!b[i]) return (void)(b[i]=x);
    38         x^=b[i];
    39     }
    40 }
    41 inline void merge(ll *b,ll *x){
    42     for(int i=61;i>=0;--i)
    43     if(x[i]) get(b,x[i]);
    44 }
    45 inline void init(int i){
    46     for(int j=1;j<20;++j){
    47         fa[i][j]=fa[fa[i][j-1]][j-1];
    48         memcpy(b[i][j],b[i][j-1],sizeof(b[i][j-1]));
    49         merge(b[i][j],b[fa[i][j-1]][j-1]);
    50     }
    51 }
    52 void dfs(int u,int f){
    53     fa[u][0]=f,dep[u]=dep[f]+1,init(u);
    54     for(int i=head[u];i;i=Next[i])
    55     if(ver[i]!=f) dfs(ver[i],u);
    56 }
    57 void LCA(int u,int v){
    58     if(dep[u]<dep[v]) swap(u,v);
    59     for(int i=20;i>=0;--i)
    60     if(dep[fa[u][i]]>=dep[v])
    61     merge(ans,b[u][i]),u=fa[u][i];
    62     if(u==v) return (void)(merge(ans,b[u][0]));
    63     for(int i=20;i>=0;--i)
    64     if(fa[u][i]!=fa[v][i]){
    65         merge(ans,b[u][i]),merge(ans,b[v][i]);
    66         u=fa[u][i],v=fa[v][i];
    67     }
    68     merge(ans,b[u][0]),merge(ans,b[v][0]),merge(ans,b[fa[u][0]][0]);
    69 }
    70 int main(){
    71 //    freopen("testdata.in","r",stdin);
    72     n=read(),q=read();
    73     for(int i=1;i<=n;++i)
    74     get(b[i][0],val[i]=read());
    75     for(int i=1,u,v;i<n;++i)
    76     u=read(),v=read(),add(u,v),add(v,u);
    77     dfs(1,0);
    78     while(q--){
    79         memset(ans,0,sizeof(ans));
    80         int u=read(),v=read();
    81         LCA(u,v);
    82         sum=0;
    83         for(int i=61;i>=0;--i)
    84         cmax(sum,sum^ans[i]);
    85         print(sum);
    86     }
    87     Ot();
    88     return 0;
    89 }
  • 相关阅读:
    A basic Windows service in C++ (CppWindowsService)
    json转换为键值对辅助类
    函数参数复习
    python --------------网络(socket)编程
    计算器
    python------------------异常处理
    hashlib,configparser,logging模块
    面向对象之反射及内置方法
    python之--------封装
    继承进阶
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9720314.html
Copyright © 2011-2022 走看看