洛谷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]='\n'; 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 }
深深地明白自己的弱小