Educational Codeforces Round 138补题

D

题意:对于一个数组,长度为n,当gcd(a[i],i)==1时可将此数删去,后面的数往前移。某个数组[2,3]的删去数组是[1,1]和[2,1],有两个,所以这种数组被定义为模糊数组。求长度为1-n,数字范围为1-m模糊数组的个数

思路:纯纯数学题
可以发现规律,只要存在一个数gcd=1那么这个数组就是模糊数组

一开始想用dp做 比如dp[i]表示数组长度为i时模糊数组的个数 然后转移方程写成了删除一个数后 后面的数不会前移的转移方程 所以最后结果比该题少

所以就要进一步拓宽规律
只要存在某个数a[i] gcd(1~i,a[i])都大于1,说明这个数一定只能在下标为1时删去。只要每一位都满足这个条件,那么这个数组就不是模糊数组
(判断这个条件时,只需要把前1-i的这些下标的质因子相乘得到yinzi,那么m/yinzi就代表满足该1-m中满足该条件数的个数,因为对于其它的数都能写成a*yinzi+b (b<yinzi) ,b无法被yinzi整除,说明b不能被yinzi中的某个质因子整除,也就是gcd=1,能在某一位置删除)

于是可以用逆向思维 先求出长度1-n数组的数量,再求出长度为i时不是模糊数组的数量。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3e5+5;
const ll mod=998244353;
ll a[N];
ll gcd(ll x,ll y)
{
	return y==0?x:gcd(y,x%y); 
}
void solve()
{
	int n;
	ll m,cur=1,ans=0;
	cin>>n>>m;
	for (int i=1;i<=n;i++)
	{
		cur=(m%mod*cur)%mod;
		ans=(ans+cur)%mod;//忘记题目是每个长度都要选
	}
	ll yinzi=1,bad=1;
	for (int i=1;i<=n;i++)
	{
		if (gcd(yinzi,i)==1)
			yinzi=yinzi*i;//要判断m与yinzi的大小  所有不能取模 
		if (m/yinzi==0)
			break;
		bad=((m/yinzi)%mod*bad)%mod;
		ans=(ans-bad+mod)%mod;
	}
	cout<<ans;
}
int main()
{
	ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    
    int t=1;
	while (t--)
	{
		solve();
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值