解题:2017六省联考 分手是祝愿

Posted ydnhaha

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解题:2017六省联考 分手是祝愿相关的知识,希望对你有一定的参考价值。

题面

首先考虑什么是最优策略,其实这个最优策略就是从大到小一个个按。因为小的不会也不能影响大的,显然这样按是最优且必须的,于是我们枚举下因数拿vector存一下,然后直接模拟就可以搞到$50pts$了(好像因为毕姥爷的数据造水了(?)导致这么做有80pts(雾 )

那么考虑在达到$k$前的这个随机按的过程,设$exp[i]$(代码里不要这么写,exp是cmath里的一个函数)表示还需要按对$i$次时的期望,那么有

$exp[i]=frac{i}{n}*1+frac{n-i}{n}*(exp[i]+exp[i+1]+1)$

其中$frac{i}{n}*1$表示这一次按对了,直接转移过去,$frac{n-i}{n}*(exp[i]+exp[i+1]+1)$表示这一次按错了,倒退回了$exp[i+1]$然后再转移回$exp[i]$

那么化简+移项就得到了一个可以递推的式子

$exp[i]=frac{(n-i)*(exp[i+1]+1)}{i}+1$

记得乘上$n!$

技术分享图片
 1 #include<cstdio>
 2 #include<vector>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int N=100005;
 7 const long long mod=100003;
 8 long long inv[N],lit[N],ex[N];
 9 long long n,k,cnt,ans,facs;
10 vector<long long> vc[N];
11 void prework()
12 {
13     facs=inv[0]=inv[1]=1;
14     for(int i=2;i<=n;i++)
15     {
16         facs=facs*i%mod;
17         inv[i]=((mod-mod/i)*inv[mod%i])%mod;
18     }
19 }
20 int main()
21 {
22     scanf("%lld%lld",&n,&k),prework();
23     for(int i=1;i<=n;i++)
24         scanf("%lld",&lit[i]);
25     for(int i=1;i<=n;i++)
26         for(int j=i;j<=n;j+=i)
27             vc[j].push_back(i);
28     for(int i=n;i;i--)
29         if(lit[i])
30         {
31             cnt++;
32             for(int j=0;j<(int)vc[i].size();j++)
33                 lit[vc[i][j]]^=1;
34         }
35     if(cnt<=k) 
36         printf("%lld",cnt*facs%mod);
37     else
38     {
39         ex[n]=1;
40         for(int i=n-1;i>k;i--)
41             ex[i]=((n-i)*(ex[i+1]+1)%mod*inv[i]%mod+1)%mod;
42         for(int i=1;i<=cnt;i++)
43             ans+=ex[i],ans%=mod;
44         printf("%lld",(ans+k)*facs%mod);
45     }
46     return 0;
47 }
View Code

 

以上是关于解题:2017六省联考 分手是祝愿的主要内容,如果未能解决你的问题,请参考以下文章

六省联考2017 分手是祝愿

洛谷 P3750 [六省联考2017]分手是祝愿

[六省联考2017]分手是祝愿

[六省联考2017]分手是祝愿

[BZOJ4872][六省联考2017]分手是祝愿

[六省联考2017]分手是祝愿 题解(期望dp)