#Trie#洛谷 7717 「EZEC-10」序列
阿新 • • 發佈:2021-07-11
Trie
分析
考慮這些關係可以用若干個連通塊表示,而可以用一個數異或邊權表示,
那麼每個連通塊有一個生成樹,而判斷非樹邊是否合法即可,
那麼問題就轉換成有多少個數異或任意一個元素均不大於\(k\),
把每個點到選定的根的異或值算出來,放進Trie裡判斷即可
程式碼
#include <cstdio> #include <cctype> #include <algorithm> #define rr register using namespace std; const int N=500011; struct node{int y,w,next;}e[N<<1]; int trie[N*30][2],n,m,k,as[N],tot,ans=1,flag,a[N],v[N]; inline signed iut(){ rr int ans=0; rr char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar(); return ans; } inline void BackTrace(){for (;tot;--tot) trie[tot][0]=trie[tot][1]=0; tot=1;} inline void Insert(int x){ rr int p=1; for (rr int i=29;~i;--i){ rr int z=(x>>i)&1; if (!trie[p][z]) trie[p][z]=++tot; p=trie[p][z]; } } inline signed dfs2(int p,int i,int now){ rr int t=trie[p][!trie[p][0]]; if (trie[p][0]&&trie[p][1]) return dfs2(trie[p][0],i-1,now|(1<<i))+dfs2(trie[p][1],i-1,now|(1<<i)); else if (t) return ((now|(1<<i))>k)?dfs2(t,i-1,now):(dfs2(t,i-1,now|(1<<i))+(1<<i)); else return now<=k; } inline void dfs1(int x){ v[x]=1,Insert(a[x]); for (rr int i=as[x];i;i=e[i].next){ if (flag) return; if (v[e[i].y]){ if ((a[x]^e[i].w)!=a[e[i].y]) {flag=1; return;} }else a[e[i].y]=a[x]^e[i].w,dfs1(e[i].y); } } signed main(){ n=iut(),m=iut(),k=iut(); for (rr int i=1;i<=m;++i){ rr int x=iut(),y=iut(),w=iut(); e[i<<1]=(node){y,w,as[x]},as[x]=i<<1; e[i<<1|1]=(node){x,w,as[y]},as[y]=i<<1|1; } for (rr int i=1;i<=n;++i) if (!v[i]){ BackTrace(),flag=0,dfs1(i); if (flag) return !printf("0"); ans=1ll*ans*dfs2(1,29,0)%1000000007; } return !printf("%d",ans); }