hdu 5514 Frogs(容斥)

文章目录

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5514
感觉学姐好厉害啊~每次的容斥题都做出来了T_T

题意:浓缩之后就是,给一个m,然后给n个数,给的这n个数必须是m的因子(因为根据题意是求的gcd),然后问给的这n个数每个数不互质的数的和?

如果n比较小的话很容易想到容斥,但是n这么大,哇怎么容斥嘛T_T

根据学姐的步骤:
①:先把m分解,找出他的所有的因子
②:把这n个数的及其倍数并且是m的因子的数标记Mp[x]=1
③:关键的一步:Mp[ki]-=Mp[i],就是说轮到计算ki的时候,他对应的Mp要减去他的约数,因为在之前已经计算过了,感觉就是这里是最难理解的地方

好来详细看哈第③步:

在这里插入图片描述

看,这个Mp很牛皮,比如说看12这个数,就是Mp[2]+Mp[3]+Mp[4]+Mp[12],总共加起来等于1,说明就只加过一次12

可是我还是不知道学姐他是怎么想到的,她说她是随便试了几次试出来的。。。先试了试取反,然后又试了试每次减1什么的,然后就试出来了T_T

/*求m以内n个数每个数的倍数的和,但是要求这n个数都是m的因子*/
#include"bits/stdc++.h"
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
const int MOD=1e9+7;
vector<LL>factor;
int main()
{
	int T;
	cin>>T;
	for(int Case=1; Case<=T; Case++)
	{
		map<LL,LL>Mp;
		factor.clear();
		LL N,M;
		cin>>N>>M;
		for(LL i=1; i*i<=M; i++)
		{
			if(M%i)continue;
			factor.push_back(i);
			if(i==M/i)continue;
			factor.push_back(M/i);
		}
		sort(factor.begin(),factor.end());//因子要从小到大排序 
		int flag=0;
		int len=factor.size();
		for(int i=1; i<=N; i++)
		{
			LL t;
			cin>>t;
			t=__gcd(t,M);
			if(t==1)flag=1;//要是gcd=1的话,就全都有 
			for(int j=1; j<len-1; j++)if(factor[j]%t==0)Mp[factor[j]]=1;
		}
		if(flag)
		{
			cout<<"Case #"<<Case<<": "<<M*(M-1)/2<<endl;
			continue;
		}
		LL sum=0;
		for(int i=1; i<len-1; i++)
		{
			LL cnt=(M-1)/factor[i];
			sum+=(factor[i]+cnt*factor[i])*cnt/2*Mp[factor[i]];//Mp就是用来容斥看是加多少还是减多少的 
			for(int j=i+1; j<len-1; j++)if(factor[j]%factor[i]==0)Mp[factor[j]]-=Mp[factor[i]];//这句话是关键~ 
		}
		cout<<"Case #"<<Case<<": "<<sum<<endl;
	}
}
微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值