http://codeforces.com/contest/494/problem/D

题意:给一个数组,和一个坏质数集合,可以无数次地让1到i这些所有数字除以他们的gcd,然后要求Σf(a[i])的最大值,其中

f(x)=f(x/p)+1,p为x的最小质数,且p不为坏质数

f(x/p)-1 ,p为x的最小质数,且p为坏质数

思路:我们考虑,如果f[j]取了1到j的gcd,那么对后面的决策并没有任何影响,因为我们统计的贡献,只统计1到i这个部分,不统计i以后的部分。

略坑,不知道第一次被什么卡了超时。。就写哈希了。。

 #include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<map>
#include<set>
std::map<int,int>mp;
std::set<int>b;
int n,m,f[],g[],a[];
int read(){
char ch=getchar();int t=,f=;
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
int gcd(int a,int b){
if (b==) return a;
else return gcd(b,a%b);
}
int F(int x){
if (x<=) return ;
if (b.count(x)) return -;
int rec=x,res=;
if (mp.find(rec)!=mp.end()) return mp[rec];
int d=,cnt=;
for (int i=;i*i<=rec;i++){
int p=i;
if (x%p==){
if (b.count(p)) d=-;else d=;
while (x%p==) x/=p,cnt+=d;
}
}
if (x!=){
if (b.count(x)) d=-;else d=;
cnt+=d;
}
return (mp[rec]=cnt);
}
int main(){
n=read();m=read();
for (int i=;i<=n;i++) a[i]=read();
for (int i=;i<=m;i++) {int x=read();b.insert(x);}
int ans=;
g[]=a[];
for (int i=;i<=n;i++) g[i]=gcd(g[i-],a[i]);
for (int i=;i<=n;i++)
ans+=F(a[i]);
f[]=ans;
for (int i=;i<=n;i++){
int s=F(g[i]);
f[i]=-0x3f3f3f3f;
for (int j=i-;j>=;j--)
f[i]=std::max(f[i],f[j]-s*(i-j));
}
ans=-0x3f3f3f3f;
for (int i=;i<=n;i++) ans=std::max(ans,f[i]);
printf("%d\n",ans);
}

还有一种贪心做法,就是从后往前取,能取就取,直到变小为止。

 #include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<map>
#include<set>
std::map<int,int>mp;
std::set<int>b;
int n,m,f[],g[],a[];
int read(){
char ch=getchar();int t=,f=;
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
int gcd(int a,int b){
if (b==) return a;
else return gcd(b,a%b);
}
int F(int x){
if (x<=) return ;
if (b.count(x)) return -;
int rec=x,res=;
if (mp.find(rec)!=mp.end()) return mp[rec];
int d=,cnt=;
for (int i=;i*i<=rec;i++){
int p=i;
if (x%p==){
if (b.count(p)) d=-;else d=;
while (x%p==) x/=p,cnt+=d;
}
}
if (x!=){
if (b.count(x)) d=-;else d=;
cnt+=d;
}
return (mp[rec]=cnt);
}
int main(){
n=read();m=read();
for (int i=;i<=n;i++) a[i]=read();
for (int i=;i<=m;i++) {int x=read();b.insert(x);}
int ans=;
g[]=a[];
for (int i=;i<=n;i++) g[i]=gcd(g[i-],a[i]);
for (int i=;i<=n;i++)
ans+=F(a[i]);
for (int i=n;i>=;i--){
int s=F(g[i]);
if (s<){
ans-=s*i;
int t=g[i];
for (int j=;j<=i;j++)
g[j]/=t;
}
}
printf("%d\n",ans);
}

Codeforces 494D Upgrading Array的更多相关文章

  1. Codeforces 402D Upgrading Array:贪心 + 数学

    题目链接:http://codeforces.com/problemset/problem/402/D 题意: 给你一个长度为n的数列a[i],又给出了m个“坏质数”b[i]. 定义函数f(s),其中 ...

  2. CodeForces 402D Upgrading Array (数学+DP)

    题意:给出一个数列,可以进行一种操作将某一个前缀除去他们的gcd,有一个函数f(x),f(1) = 0 , f(x) = f(x/p)+1,f(x) = f(x/p)-1(p是坏素数), 求 sum( ...

  3. Codeforces 482B Interesting Array(线段树)

    题目链接:Codeforces 482B Interesting Array 题目大意:给定一个长度为N的数组,如今有M个限制,每一个限制有l,r,q,表示从a[l]~a[r]取且后的数一定为q,问是 ...

  4. Codeforces 1077C Good Array 坑 C

    Codeforces 1077C Good Array https://vjudge.net/problem/CodeForces-1077C 题目: Let's call an array good ...

  5. codeforces 482B. Interesting Array【线段树区间更新】

    题目:codeforces 482B. Interesting Array 题意:给你一个值n和m中操作,每种操作就是三个数 l ,r,val. 就是区间l---r上的与的值为val,最后问你原来的数 ...

  6. codeforces 407C Curious Array

    codeforces 407C Curious Array UPD: 我觉得这个做法比较好理解啊 参考题解:https://www.cnblogs.com/ChopsticksAN/p/4908377 ...

  7. codeforces 797 E. Array Queries【dp,暴力】

    题目链接:codeforces 797 E. Array Queries   题意:给你一个长度为n的数组a,和q个询问,每次询问为(p,k),相应的把p转换为p+a[p]+k,直到p > n为 ...

  8. codeforces 402 D. Upgrading Array(数论+贪心)

    题目链接:http://codeforces.com/contest/402/problem/D 题意:给出一个a串和素数串b .f(1) = 0; p为s的最小素因子如果p不属于b , 否则 . a ...

  9. codeforces Upgrading Array

    思路:对于每个数分解质因子然后记录每一个质因子的个数,对与在b中出现的质因子就减去1,否则加1,求出总的,然后从后面一次对它们的最大公约数,然后判断除以最大公约数之后,改变量是不是变化,求最大值,变化 ...

随机推荐

  1. Qt自定义sleep延时函数(巧妙的使用时间差,但这样似乎CPU满格,而不是沉睡)

    Qt不像VC++的win32/MFC编程那样,提供了现成的sleep函数可供调用.Qt把sleep函数封装在QThread类中.子线程可以调用sleep函数.但是如果用户想在主线程实现延时功能,该怎么 ...

  2. Windows进程间通信的各种方法

    原文:Windows进程间通信的各种方法 进程是装入内存并准备执行的程序,每个进程都有私有的虚拟地址空间,由代码.数据以及它可利用的系统资源(如文件.管道等)组成.多进程/多线程是Windows操作系 ...

  3. DateTime字段控件值显示短格式的做法

    后台取dateTime格式,前台格式化就好了 <input type="text" name="txtPartyTime" id="txtPar ...

  4. One手动玩转

    <preface p2 by Ruiy,我就在开头简单奇葩两句!> 老周被查,涉及到政治问题,我先就不聊了,但Ruiy叹那,都查到七*务了,土党唱哪一出! 能基本玩转OpenNebula都 ...

  5. MySQL server version for the right syntax to use near &#39;type=InnoDB&#39; at line 1

    转载请注明出处:http://blog.csdn.net/bettarwang/article/details/40180271 在执行一个Hibernate的演示样例时,配置了<propert ...

  6. [ES6] ITERATORS

    Iterables return an iterator object. This object knows how to access items from a collection 1 at a ...

  7. spring 中StoredProcedure的使用方法

    StoredProcedure是一个抽象类,必须写一个子类来继承它,这个类是用来简化JDBCTemplate运行存储过程操作的. 首先我们写一个实现类: package com.huaye.frame ...

  8. Chapter 4: Spring and AOP:Spring's AOP Framework -- draft

    Spring's AOP Framework Let's begin by looking at Spring's own AOP framework - a proxy-based framewor ...

  9. JS 事件冒泡整理 浏览器的事件流

    JavaScript与HTML的交互通过事件来实现.而浏览器的事件流是一个非常重要的概念.不去讨论那些古老的浏览器有事件捕获与事件冒泡的争议, 只需要知道在DOM2中规定的事件流包括了三个部分,事件捕 ...

  10. 伸缩放大的js

    window.onload = function() {         var div1 = document.getElementById('div1');         div1.onmous ...