Luogu
题解
按灯问题基本有两个性质:
- 按的顺序无关
- 一个灯按一次以上没有意义
剩下的部分就可以参考 Sengxian's Blog 了。
怎么能想到这种东西呢…… 递推期望的时候,一个状态 \(f_i\) 可能走到好几个状态,又走回来这个状态,可以得到一个 \(f_i\) 关于 \(f_i\) 能到达的状态 \(f_j\) 的式子,并且式子中很可能也有 \(f_i\) 自己。于是就可以愉快地解了。
代码
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
| #include<iostream> #include<vector> using namespace std;
typedef long long ll; const int N=100000+5,MOD=100003,M=32+5; ll f[N],inv[N];
ll QPow(ll bas,int t){ ll ret=1;bas%=MOD; for(;t;t>>=1,bas=bas*bas%MOD) if(t&1)ret=ret*bas%MOD; return ret; }
int n,lim; bool a[N]; vector<int> d[N];
int main(){ ios::sync_with_stdio(0);
cin>>n>>lim; for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++) for(int j=i;j<=n;j+=i) d[j].push_back(i);
int cnt=0; for(int i=n;i>0;i--){ if(a[i]){ for(int j=0;j<d[i].size();j++) a[d[i][j]]^=1; cnt++; } }
ll ans=0,fac=1; for(int i=0;i<MOD;i++) inv[i]=QPow(i,MOD-2); for(int i=n;i>0;i--){ if(i>lim)f[i]=(f[i+1]*(n-i)+n)*inv[i]%MOD; else f[i]=1; if(i<=cnt)ans=(ans+f[i])%MOD; fac=fac*i%MOD; }
cout<<ans*fac%MOD;
return 0; }
|