rEdWhitE_uMbrElla @ 2019-02-21 21:15:59
今天是@SLF_LLL_SPFA OI的最后一天,今年年初,两开花,多多关注。。。
但明天我是真的要退役了。。于是这题便成了最后一题
不知道为什么LojAC,LG非要卡常数才能过。。不然15。。即使数据被加强了。。也不至于这样。。想知道哪里写丑了。。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
constexpr int N=1<<21,MOD=998244353;
namespace IO{
inline char gc() {
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
template<typename __Type_of__scan>
inline void read(__Type_of__scan &x) {
__Type_of__scan f=1;
x=0;
char s=gc();
while(s<'0'||s>'9') {
if(s=='-')f=-1;
s=gc();
}
while(s>='0'&&s<='9') {
x=x*10+s-'0';
s=gc();
}
x*=f;
}
char buf[100000],*pp=buf;
inline void pc(const char c) {
if(pp-buf==100000)fwrite(buf,1,100000,stdout),pp=buf;
*pp++=c;
}
template<typename __Type_of__preprint>
inline void fsh(__Type_of__preprint x) {
if(x<0) {
pc('-');
x=-x;
}
if(x>9)fsh(x/10);
pc(x%10+'0');
}
template<typename __Type_of__print>
inline void print(__Type_of__print x) {
fsh(x);
fwrite(buf,1,pp-buf,stdout);
pp=buf;
}
}
int n,m,ss,p,s[22][22],val[22],deg[22],f[22][N],g[22][N],sum[N],cnt[N],inv[N],rec[N];
namespace math{
inline int add(const int &x,const int &y) {
return x+y>=MOD?x+y-MOD:x+y;
}
inline int qpow(int x,int y){
int ans=1;
while(y) {
if(y&1) ans=1LL*ans*x%MOD;
x=1LL*x*x%MOD,y>>=1;
}
return ans;
}
inline void FWT(int *arr,int n,int op){
for(int i=1;i<n;i<<=1)
for(int q=i<<1,j=0;j<n;j+=q)
for(int k=0;k^i;++k)
arr[i+j+k]=math::add(arr[i+j+k],op==1?arr[j+k]:MOD-arr[j+k]);
}
}
namespace us{
int fa[N];
inline void init(int x){
for(int i=1;i<=x;++i) fa[i]=i;
}
inline int find(int x) {
if(fa[x]!=x) fa[x]=us::find(fa[x]);
return fa[x];
}
inline void merge(int x,int y){
int fx=us::find(x),fy=us::find(y);
if(fx!=fy) fa[fx]=fy;
}
}
int main(){
IO::read(n),IO::read(m),IO::read(p),ss=1<<n,g[0][0]=inv[0]=inv[1]=1,math::FWT(g[0],ss,1);
for(int i=2;i<=100*n;++i) inv[i]=1LL*inv[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1,x,y;i<=m;++i) IO::read(x),IO::read(y),s[x][y]=s[y][x]=1;
for(int i=1;i<=n;++i) IO::read(val[i]);
for(int i=1;i^ss;++i) cnt[i]=cnt[i>>1]+(i&1);
for(int i=1,lst=0;i^ss;++i){
us::init(n);
for(int j=1;j<=n;++j)
if((1<<(j-1))&i){
sum[i]=math::add(sum[i],val[j]);
for(int k=j+1;k<=n;++k)
if(s[j][k]&&((1<<(k-1))&i)) ++deg[j],++deg[k],us::merge(j,k);
}
for(int j=1;j<=n;++j)
if(deg[j]&1) {rec[i]=1;break;}
for(int j=1;j<=n;++j)
if((1<<(j-1))&i){
if(lst&&us::find(j)^lst) {rec[i]=1;break;}
lst=us::find(j);
}
lst=0,memset(deg,0,sizeof(deg));
}
for(int k=0;k^ss;++k) if(rec[k]) f[cnt[k]][k]=math::qpow(sum[k],p);
for(int i=1;i<=n;++i){
math::FWT(f[i],ss,1);
for(int j=1;j<=i;++j)
for(int k=0;k^ss;++k)
g[i][k]=(1LL*f[j][k]*g[i-j][k]+g[i][k])%MOD;
math::FWT(g[i],ss,-1);
for(int k=0;k^ss;++k)
if(cnt[k]^i) g[i][k]=0;
else g[i][k]=1LL*g[i][k]*math::qpow(inv[sum[k]],p)%MOD;
if(i^n) math::FWT(g[i],ss,1);
}
IO::print(g[n][ss-1]);
}
by RiverFun @ 2019-02-21 21:20:39
所以dalao为什么要退役
by 吴勉之 @ 2019-02-21 21:40:59
蒟蒻只是来前排抢沙发的,路过QAQ
。。。。。。orz(逃)