看了知乎一位大佬的文章,用st表优化了查询,在st表中维护线性基 让lognN^2的查询 少了个log
加了很多优化的方法 但无济于事
但是这样跑了9000ms 依然没法过 优化了一下线性基的查询方式 从枚举位数变成了类似lowbit的__lg(返回最大的1的位置)
不知道具体怎么算的优化 现在时间大概是4500ms
#include<bits/stdc++.h> #define close std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const ll MAXN = 2e5+7; const ll mod = 1e9+7; const ll inf = 0x3f3f3f3f; const int N = 20; struct VEC { int d[N]; int siz=0; void insert(ll x) { while(x) { int p=__lg(x); if(!d[p]) {d[p]=x;siz++; break;} x^=d[p]; } } bool find(int x) { while(x) { int p=__lg(x); if(!d[p]) {return false;} x^=d[p]; } return true; } void insert( VEC &b) { for(int i=N-1; i>=0; i--) { if(b.d[i]) { insert(b.d[i]); } } } }; VEC merge(VEC a,VEC b) { if(a.siz==N) { return a; } if(b.siz==N) { return b; } VEC c=a; c.insert(b); return c; } int siz[MAXN],f[MAXN],hson[MAXN],deep[MAXN],top[MAXN],dfn[MAXN],rdfn[MAXN],rak[MAXN],cnt; VEC a[MAXN]; VEC RMQ[MAXN][20]; int n; void init() { for(int i=1; i<=n; i++) { RMQ[i][0]=a[rak[i]]; } for(int i=1; (1<<i)<=n; i++) { for(int j=1; j+(1<<i)-1<=n; j++) { RMQ[j][i]=merge(RMQ[j][i-1],RMQ[j+(1<<(i-1))][i-1]); } } } VEC RMQ_query(int l,int r) { int k=(int)(__lg((r-l+1))); return merge(RMQ[l][k],RMQ[r-(1<<k)+1][k]); } vector<int> adj[MAXN]; void tree_build(int u,int fa,int dep) { deep[u]=dep; siz[u]=1; f[u]=fa; hson[u]=0; for(auto &v:adj[u]) { if(v==fa) continue; tree_build(v,u,dep+1); siz[u]+=siz[v]; if(hson[u]==0||siz[v]>siz[hson[u]]) hson[u]=v; } } void tree_decom(int u,int t) { top[u]=t; cnt++; dfn[u]=cnt; rak[cnt]=u; if(hson[u]!=0) { tree_decom(hson[u],t); for(auto &v:adj[u]) { if(hson[u]!=v&&v!=f[u]) tree_decom(v,v); } } rdfn[u]=cnt; } int b[MAXN]; void solve() { cin>>n; for(int i=1; i<=n; i++) cin>>b[i]; for(int i=1; i<=n; i++) { a[i].insert(b[i]); } for(int i=1; i<n; i++) { int u,v; cin>>u>>v; adj[u].push_back(v); adj[v].push_back(u); } tree_build(1,1,0); tree_decom(1,1); init(); int q; cin>>q; for(int i=1; i<=q; i++) { int u,v,k; cin>>u>>v>>k; if(k==0){ cout<<"YES\n"; continue; } VEC ans; int flag=0; while(top[v]!=top[u]) { if(deep[top[u]]>deep[top[v]]) { if(flag) ans=merge(ans,RMQ_query(dfn[top[u]],dfn[u])); else{ flag=1; ans=RMQ_query(dfn[top[u]],dfn[u]); } u=f[top[u]]; } else { if(flag) ans=merge(ans,RMQ_query(dfn[top[v]],dfn[v])); else{ flag=1; ans=RMQ_query(dfn[top[v]],dfn[v]); } v=f[top[v]]; } } if(dfn[v]<dfn[u]) swap(u,v); if(flag) ans=merge(ans,RMQ_query(dfn[u],dfn[v])); else{ ans=RMQ_query(dfn[u],dfn[v]); } if(ans.siz==N||ans.find(k)){ cout<<"YES\n"; } else cout<<"NO\n"; } } signed main() { close; solve(); }