1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| #include <bits/stdc++.h> using namespace std; #define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout) #define fo(i,j,k) for(int i=(j),end_i=(k);i<=end_i;i++) #define fd(i,j,k) for(int i=(j),end_i=(k);i>=end_i;i--) #define DEBUG(x) cout<<#x<<"="<<x<<endl; #define all(x) (x).begin(),(x).end() #define cle(x) memset(x,0,sizeof(x)) #define ll long long #define ull unsigned ll #define db double #define lb long db #define pb push_back #define mp make_pair #define fi first #define se second inline int read() { int x=0; char ch=getchar(); bool f=0; for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1; for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48); return f?-x:x; } #define CASET fo(___,1,read()) const ll mod=998244353ll; inline ll Add(ll x,ll y){x+=y; return (x<mod)?x:x-mod;} inline ll Dec(ll x,ll y){x-=y; return (x<0)?x+mod:x;} inline ll Mul(ll x,ll y){return x*y%mod;} inline ll Pow(ll x,ll y){y%=(mod-1);ll ans=1;for(;y;y>>=1,x=x*x%mod)if(y&1) ans=ans*x%mod;return ans;} const int N=21; int x[N*N],y[N*N]; int fa[N],d[N]; ll w[1<<N],iw[1<<N]; int sum[1<<N]; int n,m,p,cnt; int find(int x) { return x!=fa[x]?fa[x]=find(fa[x]):x; } inline void merge(int x,int y) { x=find(x); y=find(y); if(x!=y) fa[x]=y; } inline bool check(int s) { fo(i,0,n-1) if(d[i]&1) return 1; int rt=-1,x; fo(i,0,n-1) if((1<<i)&s) { x=find(i); if(rt==-1) rt=x; if(rt!=x) return 1; } return 0; } ll g[N+1][1<<N],f[N+1][1<<N]; inline void FWT(ll *f,int n,int opt) { for(int i=1;i<n;i<<=1) for(int j=0;j<n;j+=(i<<1)) for(int k=0;k<i;k++) (f[i+j+k]+=opt*f[j+k]+mod)%=mod; } void init() { int i; fo(s,1,cnt-1) fo(i,0,n-1) if((1<<i)&s) { w[s]=w[s^(1<<i)]+w[1<<i]; sum[s]=sum[s^(1<<i)]+1; break; } fo(s,0,cnt-1) { fo(i,0,n-1) fa[i]=i,d[i]=0; fo(i,1,m) if(((1<<x[i])&s)&&((1<<y[i])&s)) { d[x[i]]++; d[y[i]]++; merge(x[i],y[i]); } w[s]=Pow(w[s],p); iw[s]=Pow(w[s],mod-2); f[sum[s]][s]=w[s]*check(s); } }
int main() { n=read(); m=read(); p=read(); cnt=1<<n; fo(i,1,m) x[i]=read()-1,y[i]=read()-1; fo(i,0,n-1) w[1<<i]=read(); init(); g[0][0]=1; FWT(g[0],cnt,1); fo(i,1,n) { FWT(f[i],cnt,1); fo(j,0,i-1) fo(s,0,cnt-1) g[i][s]=Add(g[i][s],Mul(g[j][s],f[i-j][s])); FWT(g[i],cnt,-1); fo(s,0,cnt-1) g[i][s]=(sum[s]==i?Mul(g[i][s],iw[s]):0); if(i!=n) FWT(g[i],cnt,1); } printf("%lld",g[n][cnt-1]); return 0; }
|