2018.10.27 codeforces402D. Upgrading Array(数论+贪心)

传送门
唉我觉得这题数据范围1e5都能做啊。。。
居然只出了2000
考完听zxyzxyzxy说我的贪心可以卡但过了?
可能今天本来是0+10+00+10+00+10+0只是运气好T1T1T1骗了100pts100pts100pts吧233.
下面讲讲贪心:
wi=∏i=1kpiaiw_i=\prod_{i=1}^kp_i^{a_i}wi=i=1kpiai
A=∑aipi是好质数,B=∑ai,pi是坏质数A=\sum_{a_i} p_i是好质数,B=\sum_{a_i},p_i是坏质数A=aipi,B=ai,pi
那么fi=A−Bf_i=A-Bfi=AB
gi=gcd(w1,w2,...,wi)g_i=gcd(w_1,w_2,...,w_i)gi=gcd(w1,w2,...,wi)
考虑j&lt;ij&lt;ij<i
gi∣gjg_i|g_jgigj
k=gjgik=\frac {g_j} {g_i}k=gigj
那么有fgj=fk+fgif_{g_j}=f_k+f_{g_i}fgj=fk+fgi
所以如果先在iii那个地方进行一次操作,无论怎么样都不会令结果变小。
于是我们从后向前算出所有有正的贡献的iii加到答案里面就行了。
代码:

#include<bits/stdc++.h>
#include<tr1/unordered_map>
using namespace std;
const int N=32005;
int n,m,pri[N],a[5005],b[5005],tot=0,sum=0,ans=0;
bool vis[N];
tr1::unordered_map<int,int>S;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
inline void init(){
	for(int i=2;i<=N-5;++i){
		if(!vis[i])pri[++tot]=i;
		for(int j=1;j<=tot&&i*pri[j]<=N-5;++j){
			int k=i*pri[j];
			vis[k]=1;
			if(i%pri[j]==0)break;
		}
	}
}
inline int calc(int x){
	int ret=0;
	for(int i=1;i<=tot&&pri[i]*pri[i]<=x;++i){
		if(x==1)break;
		if(x!=x/pri[i]*pri[i])continue;
		int cnt=0;
		while(x==x/pri[i]*pri[i])++cnt,x/=pri[i];
		if(S[pri[i]])ret-=cnt;
		else ret+=cnt; 
	}
	if(x^1){
		if(S[x])--ret;
		else ++ret;
	}
	return ret;
}
int main(){
	init();
	n=read(),m=read(),S.clear();
	for(int i=1;i<=n;++i)a[i]=read();
	for(int i=1;i<=m;++i)S[read()]=1;
	for(int i=1;i<=n;++i){
		sum+=calc(a[i]);
		if(i^1)a[i]=__gcd(a[i],a[i-1]);
		b[i]=-calc(a[i]);
	}
	int pos=n,delta=0;
	while(pos){
		if(b[pos]-delta>0)sum+=(b[pos]-delta)*pos,delta+=b[pos]-delta;
		--pos;
	}
	cout<<sum;
	return 0;
}

转载于:https://www.cnblogs.com/ldxcaicai/p/10084813.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值