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

题目传送门

题目大意: 给出一排灯泡的状态,每次修改一个灯泡时会将它编号的约数的灯泡的状态同时修改,现在随机修改灯泡,当按照最优策略还有 k k k 次操作就能全灭时就按最优策略,问期望操作次数。

题解

对于一开始的灯泡状态,按照最优策略的操作的话,需要操作的灯泡是固定的。最优策略也不难想,每次操作编号最大的就好,因为编号比他小的都不能更改它的状态,所以它是必定会被操作的。

求出需要操作几次后,就可以开始 d p dp dp 了,设 f [ i ] f[i] f[i] 表示还有 i i i 个灯泡需要操作,转移到 f [ i − 1 ] f[i-1] f[i1] 期望需要几步。

注意这里不能设 f [ i ] f[i] f[i] 表示还有 i i i 个灯泡需要操作,全部操作完期望需要几步,因为 f [ i ] f[i] f[i] 既能转移到 f [ i + 1 ] f[i+1] f[i+1],又能转移到 f [ i − 1 ] f[i-1] f[i1],没法递推,所以需要确定递推方向,使它往我们想要的方向推。

那么就有: f [ i ] = 1 + n − i n ( f [ i + 1 ] + f [ i ] ) f[i]=1+\frac {n-i} n(f[i+1]+f[i]) f[i]=1+nni(f[i+1]+f[i])

加号前的 1 1 1 表示这一次操作花费了一个步数,如果成功操作到了需要操作的灯泡,那么就成功转移到了 f [ i − 1 ] f[i-1] f[i1],没有额外代价,没有操作到的概率为 n − i n \frac {n-i} n nni,这样就会使得又多了一个需要操作的灯泡,所以要加上 f [ i + 1 ] f[i+1] f[i+1],然后再加上 f [ i ] f[i] f[i]

化简得到: f [ i ] = n i + n − i i f [ i + 1 ] f[i]=\frac n i+\frac {n-i} i f[i+1] f[i]=in+inif[i+1]

以及,对于 1 ≤ i ≤ k 1\leq i\leq k 1ik,有 f [ i ] = 1 f[i]=1 f[i]=1。最后把 f [ 1 ] f[1] f[1] f [ 最 优 步 数 ] f[最优步数] f[] 都加起来就可以了。

代码如下:

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define maxn 100010
#define mod 100003

int n,k,a[maxn],f[maxn];
vector<int> s[maxn];
void work()
{
	for(int i=1;i<=n;i++)
	for(int j=i;j<=n;j+=i)
	s[j].push_back(i);
}
int ksm(int x,int y)
{
	int re=1;
	while(y)
	{
		if(y&1)re=1ll*re*x%mod;
		x=1ll*x*x%mod;y>>=1;
	}
	return re;
}
#define inv(x) ksm(x,mod-2)
int ans=0;

int main()
{
	scanf("%d %d",&n,&k); work();
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	int tot=0; f[n]=1;
	for(int i=n;i>=1;i--)if(a[i])
	{for(int j=0;j<s[i].size();j++)a[s[i][j]]^=1; tot++;}
	if(tot<k)ans=tot;
	else
	{
		for(int i=n-1;i>0;i--)f[i]=1ll*(1ll*n+1ll*(n-i)*f[i+1]%mod)*inv(i)%mod;
		for(int i=tot;i>k;i--)ans=(ans+f[i])%mod; ans=(ans+k)%mod;
	}
	for(int i=1;i<=n;i++)ans=1ll*ans*i%mod;
	printf("%d\n",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值